blob: 7db95a7ea02e1b62fe551aba9987ec636defe2b1 [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"
Ian Elliott1f0911e2022-09-09 16:31:47 -060041#include "../skia/SkiaVkRenderEngine.h"
Ana Krulec9bc9dc62020-02-26 12:16:40 -080042#include "../threaded/RenderEngineThreaded.h"
Alec Mouri6e57f682018-09-29 20:45:08 -070043
Alec Mouri1089aed2018-10-25 21:33:57 -070044constexpr int DEFAULT_DISPLAY_WIDTH = 128;
45constexpr int DEFAULT_DISPLAY_HEIGHT = 256;
46constexpr int DEFAULT_DISPLAY_OFFSET = 64;
Vishnu Nair16efdbf2019-12-10 11:55:42 -080047constexpr bool WRITE_BUFFER_TO_FILE_ON_FAILURE = false;
Alec Mouri1089aed2018-10-25 21:33:57 -070048
Alec Mouri6e57f682018-09-29 20:45:08 -070049namespace android {
Derek Sollenbergerd3f60652021-06-11 15:34:36 -040050namespace renderengine {
Alec Mouri6e57f682018-09-29 20:45:08 -070051
Alec Mouri5a493722022-01-26 16:43:02 -080052namespace {
53
54double EOTF_PQ(double channel) {
55 float m1 = (2610.0 / 4096.0) / 4.0;
56 float m2 = (2523.0 / 4096.0) * 128.0;
57 float c1 = (3424.0 / 4096.0);
58 float c2 = (2413.0 / 4096.0) * 32.0;
59 float c3 = (2392.0 / 4096.0) * 32.0;
60
61 float tmp = std::pow(std::clamp(channel, 0.0, 1.0), 1.0 / m2);
62 tmp = std::fmax(tmp - c1, 0.0) / (c2 - c3 * tmp);
63 return std::pow(tmp, 1.0 / m1);
64}
65
66vec3 EOTF_PQ(vec3 color) {
67 return vec3(EOTF_PQ(color.r), EOTF_PQ(color.g), EOTF_PQ(color.b));
68}
69
70double EOTF_HLG(double channel) {
71 const float a = 0.17883277;
72 const float b = 0.28466892;
73 const float c = 0.55991073;
74 return channel <= 0.5 ? channel * channel / 3.0 : (exp((channel - c) / a) + b) / 12.0;
75}
76
77vec3 EOTF_HLG(vec3 color) {
78 return vec3(EOTF_HLG(color.r), EOTF_HLG(color.g), EOTF_HLG(color.b));
79}
80
81double OETF_sRGB(double channel) {
82 return channel <= 0.0031308 ? channel * 12.92 : (pow(channel, 1.0 / 2.4) * 1.055) - 0.055;
83}
84
85int sign(float in) {
86 return in >= 0.0 ? 1 : -1;
87}
88
89vec3 OETF_sRGB(vec3 linear) {
90 return vec3(sign(linear.r) * OETF_sRGB(linear.r), sign(linear.g) * OETF_sRGB(linear.g),
91 sign(linear.b) * OETF_sRGB(linear.b));
92}
93
Alec Mouri9bcd1d12022-04-21 22:16:56 +000094// clang-format off
95// Converts red channels to green channels, and zeroes out an existing green channel.
96static const auto kRemoveGreenAndMoveRedToGreenMat4 = mat4(0, 1, 0, 0,
97 0, 0, 0, 0,
98 0, 0, 1, 0,
99 0, 0, 0, 1);
100// clang-format on
101
Alec Mouri5a493722022-01-26 16:43:02 -0800102} // namespace
103
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800104class RenderEngineFactory {
105public:
106 virtual ~RenderEngineFactory() = default;
107
108 virtual std::string name() = 0;
Alec Mouric0aae732021-01-12 13:32:18 -0800109 virtual renderengine::RenderEngine::RenderEngineType type() = 0;
110 virtual std::unique_ptr<renderengine::RenderEngine> createRenderEngine() = 0;
Ian Elliott1f0911e2022-09-09 16:31:47 -0600111 virtual bool typeSupported() = 0;
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -0400112 virtual bool useColorManagement() const = 0;
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800113};
114
Ian Elliott32f9e692022-11-22 15:30:29 -0700115#ifdef RE_SKIAVK
Ian Elliott1f0911e2022-09-09 16:31:47 -0600116class SkiaVkRenderEngineFactory : public RenderEngineFactory {
117public:
118 std::string name() override { return "SkiaVkRenderEngineFactory"; }
119
120 renderengine::RenderEngine::RenderEngineType type() {
121 return renderengine::RenderEngine::RenderEngineType::SKIA_VK;
122 }
123
124 std::unique_ptr<renderengine::RenderEngine> createRenderEngine() override {
125 std::unique_ptr<renderengine::RenderEngine> re = createSkiaVkRenderEngine();
126 return re;
127 }
128
129 std::unique_ptr<renderengine::skia::SkiaVkRenderEngine> createSkiaVkRenderEngine() {
130 renderengine::RenderEngineCreationArgs reCreationArgs =
131 renderengine::RenderEngineCreationArgs::Builder()
132 .setPixelFormat(static_cast<int>(ui::PixelFormat::RGBA_8888))
133 .setImageCacheSize(1)
134 .setUseColorManagerment(false)
135 .setEnableProtectedContext(false)
136 .setPrecacheToneMapperShaderOnly(false)
137 .setSupportsBackgroundBlur(true)
138 .setContextPriority(renderengine::RenderEngine::ContextPriority::MEDIUM)
139 .setRenderEngineType(type())
140 .setUseColorManagerment(useColorManagement())
141 .build();
142 return renderengine::skia::SkiaVkRenderEngine::create(reCreationArgs);
143 }
144
145 bool typeSupported() override {
146 return skia::SkiaVkRenderEngine::canSupportSkiaVkRenderEngine();
147 }
148 bool useColorManagement() const override { return false; }
149 void skip() { GTEST_SKIP(); }
150};
151
152class SkiaVkCMRenderEngineFactory : public SkiaVkRenderEngineFactory {
153public:
154 bool useColorManagement() const override { return true; }
155};
Ian Elliott32f9e692022-11-22 15:30:29 -0700156#endif // RE_SKIAVK
157
Alec Mouri0eab3e82020-12-08 18:10:27 -0800158class SkiaGLESRenderEngineFactory : public RenderEngineFactory {
159public:
Alec Mouric0aae732021-01-12 13:32:18 -0800160 std::string name() override { return "SkiaGLRenderEngineFactory"; }
Alec Mouri0eab3e82020-12-08 18:10:27 -0800161
Alec Mouric0aae732021-01-12 13:32:18 -0800162 renderengine::RenderEngine::RenderEngineType type() {
163 return renderengine::RenderEngine::RenderEngineType::SKIA_GL;
164 }
165
166 std::unique_ptr<renderengine::RenderEngine> createRenderEngine() override {
Alec Mouri0eab3e82020-12-08 18:10:27 -0800167 renderengine::RenderEngineCreationArgs reCreationArgs =
168 renderengine::RenderEngineCreationArgs::Builder()
169 .setPixelFormat(static_cast<int>(ui::PixelFormat::RGBA_8888))
170 .setImageCacheSize(1)
171 .setEnableProtectedContext(false)
172 .setPrecacheToneMapperShaderOnly(false)
173 .setSupportsBackgroundBlur(true)
174 .setContextPriority(renderengine::RenderEngine::ContextPriority::MEDIUM)
Alec Mouric0aae732021-01-12 13:32:18 -0800175 .setRenderEngineType(type())
Alec Mourid2bcbae2021-06-28 17:02:17 -0700176 .setUseColorManagerment(useColorManagement())
Alec Mouri0eab3e82020-12-08 18:10:27 -0800177 .build();
Alec Mouric0aae732021-01-12 13:32:18 -0800178 return renderengine::skia::SkiaGLRenderEngine::create(reCreationArgs);
Alec Mouri0eab3e82020-12-08 18:10:27 -0800179 }
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -0400180
Ian Elliott1f0911e2022-09-09 16:31:47 -0600181 bool typeSupported() override { return true; }
Alec Mourid2bcbae2021-06-28 17:02:17 -0700182 bool useColorManagement() const override { return false; }
Alec Mouri0eab3e82020-12-08 18:10:27 -0800183};
184
185class SkiaGLESCMRenderEngineFactory : public RenderEngineFactory {
186public:
Alec Mouric0aae732021-01-12 13:32:18 -0800187 std::string name() override { return "SkiaGLCMRenderEngineFactory"; }
Alec Mouri0eab3e82020-12-08 18:10:27 -0800188
Alec Mouric0aae732021-01-12 13:32:18 -0800189 renderengine::RenderEngine::RenderEngineType type() {
190 return renderengine::RenderEngine::RenderEngineType::SKIA_GL;
191 }
192
193 std::unique_ptr<renderengine::RenderEngine> createRenderEngine() override {
Alec Mouri0eab3e82020-12-08 18:10:27 -0800194 renderengine::RenderEngineCreationArgs reCreationArgs =
195 renderengine::RenderEngineCreationArgs::Builder()
196 .setPixelFormat(static_cast<int>(ui::PixelFormat::RGBA_8888))
197 .setImageCacheSize(1)
198 .setEnableProtectedContext(false)
199 .setPrecacheToneMapperShaderOnly(false)
200 .setSupportsBackgroundBlur(true)
201 .setContextPriority(renderengine::RenderEngine::ContextPriority::MEDIUM)
Alec Mouric0aae732021-01-12 13:32:18 -0800202 .setRenderEngineType(type())
Alec Mourid2bcbae2021-06-28 17:02:17 -0700203 .setUseColorManagerment(useColorManagement())
Alec Mouri0eab3e82020-12-08 18:10:27 -0800204 .build();
Alec Mouric0aae732021-01-12 13:32:18 -0800205 return renderengine::skia::SkiaGLRenderEngine::create(reCreationArgs);
Alec Mouri0eab3e82020-12-08 18:10:27 -0800206 }
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -0400207
Ian Elliott1f0911e2022-09-09 16:31:47 -0600208 bool typeSupported() override { return true; }
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -0400209 bool useColorManagement() const override { return true; }
Alec Mouri0eab3e82020-12-08 18:10:27 -0800210};
211
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800212class RenderEngineTest : public ::testing::TestWithParam<std::shared_ptr<RenderEngineFactory>> {
213public:
Alec Mouria90a5702021-04-16 16:36:21 +0000214 std::shared_ptr<renderengine::ExternalTexture> allocateDefaultBuffer() {
215 return std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800216 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -0700217 ExternalTexture>(sp<GraphicBuffer>::
218 make(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT,
219 HAL_PIXEL_FORMAT_RGBA_8888, 1,
220 GRALLOC_USAGE_SW_READ_OFTEN |
221 GRALLOC_USAGE_SW_WRITE_OFTEN |
222 GRALLOC_USAGE_HW_RENDER |
223 GRALLOC_USAGE_HW_TEXTURE,
224 "output"),
Alec Mouria90a5702021-04-16 16:36:21 +0000225 *mRE,
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800226 renderengine::impl::ExternalTexture::Usage::READABLE |
227 renderengine::impl::ExternalTexture::Usage::
228 WRITEABLE);
Alec Mouri6e57f682018-09-29 20:45:08 -0700229 }
230
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800231 // Allocates a 1x1 buffer to fill with a solid color
Alec Mouria90a5702021-04-16 16:36:21 +0000232 std::shared_ptr<renderengine::ExternalTexture> allocateSourceBuffer(uint32_t width,
233 uint32_t height) {
234 return std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800235 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -0700236 ExternalTexture>(sp<GraphicBuffer>::
237 make(width, height, HAL_PIXEL_FORMAT_RGBA_8888, 1,
238 GRALLOC_USAGE_SW_READ_OFTEN |
239 GRALLOC_USAGE_SW_WRITE_OFTEN |
240 GRALLOC_USAGE_HW_TEXTURE,
241 "input"),
Alec Mouria90a5702021-04-16 16:36:21 +0000242 *mRE,
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800243 renderengine::impl::ExternalTexture::Usage::READABLE |
244 renderengine::impl::ExternalTexture::Usage::
245 WRITEABLE);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800246 }
247
Alec Mouricdf6cbc2021-11-01 17:21:15 -0700248 std::shared_ptr<renderengine::ExternalTexture> allocateAndFillSourceBuffer(uint32_t width,
249 uint32_t height,
250 ubyte4 color) {
251 const auto buffer = allocateSourceBuffer(width, height);
252 uint8_t* pixels;
253 buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
254 reinterpret_cast<void**>(&pixels));
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -0500255 for (uint32_t j = 0; j < height; j++) {
256 uint8_t* dst = pixels + (buffer->getBuffer()->getStride() * j * 4);
257 for (uint32_t i = 0; i < width; i++) {
258 dst[0] = color.r;
259 dst[1] = color.g;
260 dst[2] = color.b;
261 dst[3] = color.a;
262 dst += 4;
263 }
264 }
Alec Mouricdf6cbc2021-11-01 17:21:15 -0700265 buffer->getBuffer()->unlock();
266 return buffer;
267 }
268
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -0500269 std::shared_ptr<renderengine::ExternalTexture> allocateR8Buffer(int width, int height) {
Ady Abrahamd11bade2022-08-01 16:18:03 -0700270 const auto kUsageFlags =
271 static_cast<uint64_t>(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
272 GRALLOC_USAGE_HW_TEXTURE);
273 auto buffer =
274 sp<GraphicBuffer>::make(static_cast<uint32_t>(width), static_cast<uint32_t>(height),
275 android::PIXEL_FORMAT_R_8, 1u, kUsageFlags, "r8");
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -0500276 if (buffer->initCheck() != 0) {
277 // Devices are not required to support R8.
278 return nullptr;
279 }
280 return std::make_shared<
281 renderengine::impl::ExternalTexture>(std::move(buffer), *mRE,
282 renderengine::impl::ExternalTexture::Usage::
283 READABLE);
284 }
285
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800286 RenderEngineTest() {
287 const ::testing::TestInfo* const test_info =
288 ::testing::UnitTest::GetInstance()->current_test_info();
289 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800290 }
Alec Mouri1089aed2018-10-25 21:33:57 -0700291
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800292 ~RenderEngineTest() {
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800293 if (WRITE_BUFFER_TO_FILE_ON_FAILURE && ::testing::Test::HasFailure()) {
294 writeBufferToFile("/data/texture_out_");
295 }
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800296 for (uint32_t texName : mTexNames) {
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800297 mRE->deleteTextures(1, &texName);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800298 }
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800299 const ::testing::TestInfo* const test_info =
300 ::testing::UnitTest::GetInstance()->current_test_info();
301 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800302 }
303
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800304 void writeBufferToFile(const char* basename) {
305 std::string filename(basename);
306 filename.append(::testing::UnitTest::GetInstance()->current_test_info()->name());
307 filename.append(".ppm");
308 std::ofstream file(filename.c_str(), std::ios::binary);
309 if (!file.is_open()) {
310 ALOGE("Unable to open file: %s", filename.c_str());
311 ALOGE("You may need to do: \"adb shell setenforce 0\" to enable "
312 "surfaceflinger to write debug images");
313 return;
314 }
315
Alec Mouri1089aed2018-10-25 21:33:57 -0700316 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +0000317 mBuffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
318 reinterpret_cast<void**>(&pixels));
Alec Mouri1089aed2018-10-25 21:33:57 -0700319
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800320 file << "P6\n";
Alec Mouria90a5702021-04-16 16:36:21 +0000321 file << mBuffer->getBuffer()->getWidth() << "\n";
322 file << mBuffer->getBuffer()->getHeight() << "\n";
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800323 file << 255 << "\n";
324
Alec Mouria90a5702021-04-16 16:36:21 +0000325 std::vector<uint8_t> outBuffer(mBuffer->getBuffer()->getWidth() *
326 mBuffer->getBuffer()->getHeight() * 3);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800327 auto outPtr = reinterpret_cast<uint8_t*>(outBuffer.data());
328
Alec Mouria90a5702021-04-16 16:36:21 +0000329 for (int32_t j = 0; j < mBuffer->getBuffer()->getHeight(); j++) {
330 const uint8_t* src = pixels + (mBuffer->getBuffer()->getStride() * j) * 4;
331 for (int32_t i = 0; i < mBuffer->getBuffer()->getWidth(); i++) {
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800332 // Only copy R, G and B components
333 outPtr[0] = src[0];
334 outPtr[1] = src[1];
335 outPtr[2] = src[2];
336 outPtr += 3;
337
338 src += 4;
339 }
340 }
341 file.write(reinterpret_cast<char*>(outBuffer.data()), outBuffer.size());
Alec Mouria90a5702021-04-16 16:36:21 +0000342 mBuffer->getBuffer()->unlock();
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800343 }
344
345 void expectBufferColor(const Region& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
346 size_t c;
347 Rect const* rect = region.getArray(&c);
348 for (size_t i = 0; i < c; i++, rect++) {
349 expectBufferColor(*rect, r, g, b, a);
350 }
351 }
352
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -0400353 void expectBufferColor(const Point& point, uint8_t r, uint8_t g, uint8_t b, uint8_t a,
354 uint8_t tolerance = 0) {
355 expectBufferColor(Rect(point.x, point.y, point.x + 1, point.y + 1), r, g, b, a, tolerance);
356 }
357
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800358 void expectBufferColor(const Rect& rect, uint8_t r, uint8_t g, uint8_t b, uint8_t a,
359 uint8_t tolerance = 0) {
Alec Mouri4049b532021-10-15 20:59:33 -0700360 auto generator = [=](Point) { return ubyte4(r, g, b, a); };
361 expectBufferColor(rect, generator, tolerance);
362 }
363
364 using ColorGenerator = std::function<ubyte4(Point location)>;
365
366 void expectBufferColor(const Rect& rect, ColorGenerator generator, uint8_t tolerance = 0) {
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800367 auto colorCompare = [tolerance](const uint8_t* colorA, const uint8_t* colorB) {
368 auto colorBitCompare = [tolerance](uint8_t a, uint8_t b) {
369 uint8_t tmp = a >= b ? a - b : b - a;
370 return tmp <= tolerance;
371 };
372 return std::equal(colorA, colorA + 4, colorB, colorBitCompare);
Alec Mouri1089aed2018-10-25 21:33:57 -0700373 };
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800374
Alec Mouri4049b532021-10-15 20:59:33 -0700375 expectBufferColor(rect, generator, colorCompare);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800376 }
377
Alec Mouri4049b532021-10-15 20:59:33 -0700378 void expectBufferColor(const Rect& region, ColorGenerator generator,
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800379 std::function<bool(const uint8_t* a, const uint8_t* b)> colorCompare) {
380 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +0000381 mBuffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
382 reinterpret_cast<void**>(&pixels));
Alec Mouri1089aed2018-10-25 21:33:57 -0700383 int32_t maxFails = 10;
384 int32_t fails = 0;
385 for (int32_t j = 0; j < region.getHeight(); j++) {
Alec Mouria90a5702021-04-16 16:36:21 +0000386 const uint8_t* src = pixels +
387 (mBuffer->getBuffer()->getStride() * (region.top + j) + region.left) * 4;
Alec Mouri1089aed2018-10-25 21:33:57 -0700388 for (int32_t i = 0; i < region.getWidth(); i++) {
Alec Mouri4049b532021-10-15 20:59:33 -0700389 const auto location = Point(region.left + i, region.top + j);
390 const ubyte4 colors = generator(location);
391 const uint8_t expected[4] = {colors.r, colors.g, colors.b, colors.a};
392 bool colorMatches = colorCompare(src, expected);
393 EXPECT_TRUE(colorMatches)
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -0400394 << GetParam()->name().c_str() << ": "
Alec Mouri4049b532021-10-15 20:59:33 -0700395 << "pixel @ (" << location.x << ", " << location.y << "): "
396 << "expected (" << static_cast<uint32_t>(colors.r) << ", "
397 << static_cast<uint32_t>(colors.g) << ", "
398 << static_cast<uint32_t>(colors.b) << ", "
399 << static_cast<uint32_t>(colors.a) << "), "
Alec Mouri1089aed2018-10-25 21:33:57 -0700400 << "got (" << static_cast<uint32_t>(src[0]) << ", "
401 << static_cast<uint32_t>(src[1]) << ", " << static_cast<uint32_t>(src[2])
402 << ", " << static_cast<uint32_t>(src[3]) << ")";
403 src += 4;
Alec Mouri4049b532021-10-15 20:59:33 -0700404 if (!colorMatches && ++fails >= maxFails) {
Alec Mouri1089aed2018-10-25 21:33:57 -0700405 break;
406 }
407 }
408 if (fails >= maxFails) {
409 break;
410 }
411 }
Alec Mouria90a5702021-04-16 16:36:21 +0000412 mBuffer->getBuffer()->unlock();
Alec Mouri1089aed2018-10-25 21:33:57 -0700413 }
414
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800415 void expectAlpha(const Rect& rect, uint8_t a) {
Alec Mouri4049b532021-10-15 20:59:33 -0700416 auto generator = [=](Point) { return ubyte4(0, 0, 0, a); };
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800417 auto colorCompare = [](const uint8_t* colorA, const uint8_t* colorB) {
418 return colorA[3] == colorB[3];
419 };
Alec Mouri4049b532021-10-15 20:59:33 -0700420 expectBufferColor(rect, generator, colorCompare);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800421 }
422
423 void expectShadowColor(const renderengine::LayerSettings& castingLayer,
424 const renderengine::ShadowSettings& shadow, const ubyte4& casterColor,
425 const ubyte4& backgroundColor) {
426 const Rect casterRect(castingLayer.geometry.boundaries);
427 Region casterRegion = Region(casterRect);
Vishnu Nair50c0afe2022-07-11 15:04:07 -0700428 const float casterCornerRadius = (castingLayer.geometry.roundedCornersRadius.x +
429 castingLayer.geometry.roundedCornersRadius.y) /
430 2.0;
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800431 if (casterCornerRadius > 0.0f) {
432 // ignore the corners if a corner radius is set
433 Rect cornerRect(casterCornerRadius, casterCornerRadius);
434 casterRegion.subtractSelf(cornerRect.offsetTo(casterRect.left, casterRect.top));
435 casterRegion.subtractSelf(
436 cornerRect.offsetTo(casterRect.right - casterCornerRadius, casterRect.top));
437 casterRegion.subtractSelf(
438 cornerRect.offsetTo(casterRect.left, casterRect.bottom - casterCornerRadius));
439 casterRegion.subtractSelf(cornerRect.offsetTo(casterRect.right - casterCornerRadius,
440 casterRect.bottom - casterCornerRadius));
441 }
442
443 const float shadowInset = shadow.length * -1.0f;
444 const Rect casterWithShadow =
445 Rect(casterRect).inset(shadowInset, shadowInset, shadowInset, shadowInset);
446 const Region shadowRegion = Region(casterWithShadow).subtractSelf(casterRect);
447 const Region backgroundRegion = Region(fullscreenRect()).subtractSelf(casterWithShadow);
448
449 // verify casting layer
450 expectBufferColor(casterRegion, casterColor.r, casterColor.g, casterColor.b, casterColor.a);
451
452 // verify shadows by testing just the alpha since its difficult to validate the shadow color
453 size_t c;
454 Rect const* r = shadowRegion.getArray(&c);
455 for (size_t i = 0; i < c; i++, r++) {
456 expectAlpha(*r, 255);
457 }
458
459 // verify background
460 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
461 backgroundColor.a);
462 }
463
Alec Mouribd17b3b2020-12-17 11:08:30 -0800464 void expectShadowColorWithoutCaster(const FloatRect& casterBounds,
465 const renderengine::ShadowSettings& shadow,
466 const ubyte4& backgroundColor) {
467 const float shadowInset = shadow.length * -1.0f;
468 const Rect casterRect(casterBounds);
469 const Rect shadowRect =
470 Rect(casterRect).inset(shadowInset, shadowInset, shadowInset, shadowInset);
471
472 const Region backgroundRegion =
473 Region(fullscreenRect()).subtractSelf(casterRect).subtractSelf(shadowRect);
474
475 expectAlpha(shadowRect, 255);
476 // (0, 0, 0) fill on the bounds of the layer should be ignored.
477 expectBufferColor(casterRect, 255, 255, 255, 255, 254);
478
479 // verify background
480 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
481 backgroundColor.a);
482 }
483
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800484 static renderengine::ShadowSettings getShadowSettings(const vec2& casterPos, float shadowLength,
485 bool casterIsTranslucent) {
486 renderengine::ShadowSettings shadow;
487 shadow.ambientColor = {0.0f, 0.0f, 0.0f, 0.039f};
488 shadow.spotColor = {0.0f, 0.0f, 0.0f, 0.19f};
489 shadow.lightPos = vec3(casterPos.x, casterPos.y, 0);
490 shadow.lightRadius = 0.0f;
491 shadow.length = shadowLength;
492 shadow.casterIsTranslucent = casterIsTranslucent;
493 return shadow;
494 }
495
Alec Mouri1089aed2018-10-25 21:33:57 -0700496 static Rect fullscreenRect() { return Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT); }
497
498 static Rect offsetRect() {
499 return Rect(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_WIDTH,
500 DEFAULT_DISPLAY_HEIGHT);
501 }
502
503 static Rect offsetRectAtZero() {
504 return Rect(DEFAULT_DISPLAY_WIDTH - DEFAULT_DISPLAY_OFFSET,
505 DEFAULT_DISPLAY_HEIGHT - DEFAULT_DISPLAY_OFFSET);
506 }
507
Sally Qi59a9f502021-10-12 18:53:23 +0000508 void invokeDraw(const renderengine::DisplaySettings& settings,
509 const std::vector<renderengine::LayerSettings>& layers) {
Patrick Williams2e9748f2022-08-09 22:48:18 +0000510 ftl::Future<FenceResult> future =
Sally Qi4cabdd02021-08-05 16:45:57 -0700511 mRE->drawLayers(settings, layers, mBuffer, true, base::unique_fd());
Patrick Williams2e9748f2022-08-09 22:48:18 +0000512 ASSERT_TRUE(future.valid());
Sally Qi59a9f502021-10-12 18:53:23 +0000513
Patrick Williams2e9748f2022-08-09 22:48:18 +0000514 auto result = future.get();
515 ASSERT_TRUE(result.ok());
Alec Mouri1089aed2018-10-25 21:33:57 -0700516
Patrick Williams2e9748f2022-08-09 22:48:18 +0000517 auto fence = result.value();
518 fence->waitForever(LOG_TAG);
Alec Mouri1089aed2018-10-25 21:33:57 -0700519 }
520
Alec Mourid43ccab2019-03-13 12:23:45 -0700521 void drawEmptyLayers() {
Alec Mouri6e57f682018-09-29 20:45:08 -0700522 renderengine::DisplaySettings settings;
Sally Qi59a9f502021-10-12 18:53:23 +0000523 std::vector<renderengine::LayerSettings> layers;
Alec Mouric0aae732021-01-12 13:32:18 -0800524 invokeDraw(settings, layers);
Alec Mouri6e57f682018-09-29 20:45:08 -0700525 }
526
Alec Mouri1089aed2018-10-25 21:33:57 -0700527 template <typename SourceVariant>
528 void fillBuffer(half r, half g, half b, half a);
529
530 template <typename SourceVariant>
531 void fillRedBuffer();
532
533 template <typename SourceVariant>
534 void fillGreenBuffer();
535
536 template <typename SourceVariant>
537 void fillBlueBuffer();
538
539 template <typename SourceVariant>
540 void fillRedTransparentBuffer();
541
542 template <typename SourceVariant>
543 void fillRedOffsetBuffer();
544
545 template <typename SourceVariant>
546 void fillBufferPhysicalOffset();
547
548 template <typename SourceVariant>
Alec Mouri5a6d8572020-03-23 23:56:15 -0700549 void fillBufferCheckers(uint32_t rotation);
Alec Mouri1089aed2018-10-25 21:33:57 -0700550
551 template <typename SourceVariant>
552 void fillBufferCheckersRotate0();
553
554 template <typename SourceVariant>
555 void fillBufferCheckersRotate90();
556
557 template <typename SourceVariant>
558 void fillBufferCheckersRotate180();
559
560 template <typename SourceVariant>
561 void fillBufferCheckersRotate270();
562
563 template <typename SourceVariant>
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800564 void fillBufferWithLayerTransform();
565
566 template <typename SourceVariant>
Alec Mouri1089aed2018-10-25 21:33:57 -0700567 void fillBufferLayerTransform();
568
569 template <typename SourceVariant>
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800570 void fillBufferWithColorTransform();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800571
572 template <typename SourceVariant>
Alec Mouri1089aed2018-10-25 21:33:57 -0700573 void fillBufferColorTransform();
574
Alec Mouri7c94edb2018-12-03 21:23:26 -0800575 template <typename SourceVariant>
Sally Qi2019fd22021-11-22 10:19:04 -0800576 void fillBufferWithColorTransformAndSourceDataspace(const ui::Dataspace sourceDataspace);
577
578 template <typename SourceVariant>
579 void fillBufferColorTransformAndSourceDataspace();
580
581 template <typename SourceVariant>
582 void fillBufferWithColorTransformAndOutputDataspace(const ui::Dataspace outputDataspace);
583
584 template <typename SourceVariant>
585 void fillBufferColorTransformAndOutputDataspace();
586
587 template <typename SourceVariant>
KaiChieh Chuangda2845c2020-12-14 16:49:38 +0800588 void fillBufferWithColorTransformZeroLayerAlpha();
589
590 template <typename SourceVariant>
591 void fillBufferColorTransformZeroLayerAlpha();
592
593 template <typename SourceVariant>
Alec Mouri7c94edb2018-12-03 21:23:26 -0800594 void fillRedBufferWithRoundedCorners();
595
596 template <typename SourceVariant>
597 void fillBufferWithRoundedCorners();
598
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000599 template <typename SourceVariant>
Lucas Dupin19c8f0e2019-11-25 17:55:44 -0800600 void fillBufferAndBlurBackground();
601
602 template <typename SourceVariant>
Alec Mourie8489fd2021-04-29 16:08:56 -0700603 void fillSmallLayerAndBlurBackground();
604
605 template <typename SourceVariant>
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000606 void overlayCorners();
607
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800608 void fillRedBufferTextureTransform();
609
610 void fillBufferTextureTransform();
611
612 void fillRedBufferWithPremultiplyAlpha();
613
614 void fillBufferWithPremultiplyAlpha();
615
616 void fillRedBufferWithoutPremultiplyAlpha();
617
618 void fillBufferWithoutPremultiplyAlpha();
619
Alec Mouriac335532018-11-12 15:01:33 -0800620 void fillGreenColorBufferThenClearRegion();
621
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800622 template <typename SourceVariant>
623 void drawShadow(const renderengine::LayerSettings& castingLayer,
624 const renderengine::ShadowSettings& shadow, const ubyte4& casterColor,
625 const ubyte4& backgroundColor);
626
Alec Mouribd17b3b2020-12-17 11:08:30 -0800627 void drawShadowWithoutCaster(const FloatRect& castingBounds,
628 const renderengine::ShadowSettings& shadow,
629 const ubyte4& backgroundColor);
630
Alec Mouri5a493722022-01-26 16:43:02 -0800631 // Tonemaps grey values from sourceDataspace -> Display P3 and checks that GPU and CPU
632 // implementations are identical Also implicitly checks that the injected tonemap shader
633 // compiles
634 void tonemap(ui::Dataspace sourceDataspace, std::function<vec3(vec3)> eotf,
635 std::function<vec3(vec3, float)> scaleOotf);
636
Alec Mouric0aae732021-01-12 13:32:18 -0800637 void initializeRenderEngine();
638
639 std::unique_ptr<renderengine::RenderEngine> mRE;
Alec Mouria90a5702021-04-16 16:36:21 +0000640 std::shared_ptr<renderengine::ExternalTexture> mBuffer;
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800641
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800642 std::vector<uint32_t> mTexNames;
Alec Mouri6e57f682018-09-29 20:45:08 -0700643};
644
Alec Mouric0aae732021-01-12 13:32:18 -0800645void RenderEngineTest::initializeRenderEngine() {
646 const auto& renderEngineFactory = GetParam();
Alec Mouric16974e2022-09-13 17:35:48 +0000647 mRE = renderEngineFactory->createRenderEngine();
Alec Mouria90a5702021-04-16 16:36:21 +0000648 mBuffer = allocateDefaultBuffer();
Alec Mouric0aae732021-01-12 13:32:18 -0800649}
650
Alec Mouri1089aed2018-10-25 21:33:57 -0700651struct ColorSourceVariant {
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800652 static void fillColor(renderengine::LayerSettings& layer, half r, half g, half b,
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800653 RenderEngineTest* /*fixture*/) {
Alec Mouri1089aed2018-10-25 21:33:57 -0700654 layer.source.solidColor = half3(r, g, b);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800655 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700656 }
657};
658
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800659struct RelaxOpaqueBufferVariant {
660 static void setOpaqueBit(renderengine::LayerSettings& layer) {
661 layer.source.buffer.isOpaque = false;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800662 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800663 }
664
665 static uint8_t getAlphaChannel() { return 255; }
666};
667
668struct ForceOpaqueBufferVariant {
669 static void setOpaqueBit(renderengine::LayerSettings& layer) {
670 layer.source.buffer.isOpaque = true;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800671 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800672 }
673
674 static uint8_t getAlphaChannel() {
675 // The isOpaque bit will override the alpha channel, so this should be
676 // arbitrary.
Alec Mouric0aae732021-01-12 13:32:18 -0800677 return 50;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800678 }
679};
680
681template <typename OpaquenessVariant>
682struct BufferSourceVariant {
683 static void fillColor(renderengine::LayerSettings& layer, half r, half g, half b,
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800684 RenderEngineTest* fixture) {
Alec Mouria90a5702021-04-16 16:36:21 +0000685 const auto buf = fixture->allocateSourceBuffer(1, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800686 uint32_t texName;
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800687 fixture->mRE->genTextures(1, &texName);
688 fixture->mTexNames.push_back(texName);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800689
690 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +0000691 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
692 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800693
Alec Mouria90a5702021-04-16 16:36:21 +0000694 for (int32_t j = 0; j < buf->getBuffer()->getHeight(); j++) {
695 uint8_t* iter = pixels + (buf->getBuffer()->getStride() * j) * 4;
696 for (int32_t i = 0; i < buf->getBuffer()->getWidth(); i++) {
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800697 iter[0] = uint8_t(r * 255);
698 iter[1] = uint8_t(g * 255);
699 iter[2] = uint8_t(b * 255);
700 iter[3] = OpaquenessVariant::getAlphaChannel();
701 iter += 4;
702 }
703 }
704
Alec Mouria90a5702021-04-16 16:36:21 +0000705 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800706
707 layer.source.buffer.buffer = buf;
708 layer.source.buffer.textureName = texName;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800709 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800710 OpaquenessVariant::setOpaqueBit(layer);
711 }
712};
713
Alec Mouri1089aed2018-10-25 21:33:57 -0700714template <typename SourceVariant>
715void RenderEngineTest::fillBuffer(half r, half g, half b, half a) {
716 renderengine::DisplaySettings settings;
717 settings.physicalDisplay = fullscreenRect();
718 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800719 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700720
Sally Qi59a9f502021-10-12 18:53:23 +0000721 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700722
723 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800724 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700725 layer.geometry.boundaries = fullscreenRect().toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800726 SourceVariant::fillColor(layer, r, g, b, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700727 layer.alpha = a;
728
Sally Qi59a9f502021-10-12 18:53:23 +0000729 layers.push_back(layer);
Alec Mouri1089aed2018-10-25 21:33:57 -0700730
Alec Mouric0aae732021-01-12 13:32:18 -0800731 invokeDraw(settings, layers);
Alec Mouri1089aed2018-10-25 21:33:57 -0700732}
733
734template <typename SourceVariant>
735void RenderEngineTest::fillRedBuffer() {
736 fillBuffer<SourceVariant>(1.0f, 0.0f, 0.0f, 1.0f);
737 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
738}
739
740template <typename SourceVariant>
741void RenderEngineTest::fillGreenBuffer() {
742 fillBuffer<SourceVariant>(0.0f, 1.0f, 0.0f, 1.0f);
743 expectBufferColor(fullscreenRect(), 0, 255, 0, 255);
744}
745
746template <typename SourceVariant>
747void RenderEngineTest::fillBlueBuffer() {
748 fillBuffer<SourceVariant>(0.0f, 0.0f, 1.0f, 1.0f);
749 expectBufferColor(fullscreenRect(), 0, 0, 255, 255);
750}
751
752template <typename SourceVariant>
753void RenderEngineTest::fillRedTransparentBuffer() {
754 fillBuffer<SourceVariant>(1.0f, 0.0f, 0.0f, .2f);
755 expectBufferColor(fullscreenRect(), 51, 0, 0, 51);
756}
757
758template <typename SourceVariant>
759void RenderEngineTest::fillRedOffsetBuffer() {
760 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800761 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700762 settings.physicalDisplay = offsetRect();
763 settings.clip = offsetRectAtZero();
764
Sally Qi59a9f502021-10-12 18:53:23 +0000765 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700766
767 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800768 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700769 layer.geometry.boundaries = offsetRectAtZero().toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800770 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700771 layer.alpha = 1.0f;
772
Sally Qi59a9f502021-10-12 18:53:23 +0000773 layers.push_back(layer);
Alec Mouric0aae732021-01-12 13:32:18 -0800774 invokeDraw(settings, layers);
Alec Mouri1089aed2018-10-25 21:33:57 -0700775}
776
777template <typename SourceVariant>
778void RenderEngineTest::fillBufferPhysicalOffset() {
779 fillRedOffsetBuffer<SourceVariant>();
780
781 expectBufferColor(Rect(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_WIDTH,
782 DEFAULT_DISPLAY_HEIGHT),
783 255, 0, 0, 255);
784 Rect offsetRegionLeft(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_HEIGHT);
785 Rect offsetRegionTop(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_OFFSET);
786
787 expectBufferColor(offsetRegionLeft, 0, 0, 0, 0);
788 expectBufferColor(offsetRegionTop, 0, 0, 0, 0);
789}
790
791template <typename SourceVariant>
Alec Mouri5a6d8572020-03-23 23:56:15 -0700792void RenderEngineTest::fillBufferCheckers(uint32_t orientationFlag) {
Alec Mouri1089aed2018-10-25 21:33:57 -0700793 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800794 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700795 settings.physicalDisplay = fullscreenRect();
796 // Here logical space is 2x2
797 settings.clip = Rect(2, 2);
Alec Mouri5a6d8572020-03-23 23:56:15 -0700798 settings.orientation = orientationFlag;
Alec Mouri1089aed2018-10-25 21:33:57 -0700799
Sally Qi59a9f502021-10-12 18:53:23 +0000800 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700801
802 renderengine::LayerSettings layerOne;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800803 layerOne.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700804 Rect rectOne(0, 0, 1, 1);
805 layerOne.geometry.boundaries = rectOne.toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800806 SourceVariant::fillColor(layerOne, 1.0f, 0.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700807 layerOne.alpha = 1.0f;
808
809 renderengine::LayerSettings layerTwo;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800810 layerTwo.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700811 Rect rectTwo(0, 1, 1, 2);
812 layerTwo.geometry.boundaries = rectTwo.toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800813 SourceVariant::fillColor(layerTwo, 0.0f, 1.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700814 layerTwo.alpha = 1.0f;
815
816 renderengine::LayerSettings layerThree;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800817 layerThree.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700818 Rect rectThree(1, 0, 2, 1);
819 layerThree.geometry.boundaries = rectThree.toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800820 SourceVariant::fillColor(layerThree, 0.0f, 0.0f, 1.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700821 layerThree.alpha = 1.0f;
822
Sally Qi59a9f502021-10-12 18:53:23 +0000823 layers.push_back(layerOne);
824 layers.push_back(layerTwo);
825 layers.push_back(layerThree);
Alec Mouri1089aed2018-10-25 21:33:57 -0700826
Alec Mouric0aae732021-01-12 13:32:18 -0800827 invokeDraw(settings, layers);
Alec Mouri1089aed2018-10-25 21:33:57 -0700828}
829
830template <typename SourceVariant>
831void RenderEngineTest::fillBufferCheckersRotate0() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700832 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_0);
Alec Mouri1089aed2018-10-25 21:33:57 -0700833 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0,
834 255);
835 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
836 DEFAULT_DISPLAY_HEIGHT / 2),
837 0, 0, 255, 255);
838 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
839 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
840 0, 0, 0, 0);
841 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
842 DEFAULT_DISPLAY_HEIGHT),
843 0, 255, 0, 255);
844}
845
846template <typename SourceVariant>
847void RenderEngineTest::fillBufferCheckersRotate90() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700848 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_90);
Alec Mouri1089aed2018-10-25 21:33:57 -0700849 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 255, 0,
850 255);
851 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
852 DEFAULT_DISPLAY_HEIGHT / 2),
853 255, 0, 0, 255);
854 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
855 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
856 0, 0, 255, 255);
857 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
858 DEFAULT_DISPLAY_HEIGHT),
859 0, 0, 0, 0);
860}
861
862template <typename SourceVariant>
863void RenderEngineTest::fillBufferCheckersRotate180() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700864 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_180);
Alec Mouri1089aed2018-10-25 21:33:57 -0700865 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 0,
866 0);
867 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
868 DEFAULT_DISPLAY_HEIGHT / 2),
869 0, 255, 0, 255);
870 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
871 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
872 255, 0, 0, 255);
873 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
874 DEFAULT_DISPLAY_HEIGHT),
875 0, 0, 255, 255);
876}
877
878template <typename SourceVariant>
879void RenderEngineTest::fillBufferCheckersRotate270() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700880 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_270);
Alec Mouri1089aed2018-10-25 21:33:57 -0700881 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 255,
882 255);
883 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
884 DEFAULT_DISPLAY_HEIGHT / 2),
885 0, 0, 0, 0);
886 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
887 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
888 0, 255, 0, 255);
889 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
890 DEFAULT_DISPLAY_HEIGHT),
891 255, 0, 0, 255);
892}
893
894template <typename SourceVariant>
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800895void RenderEngineTest::fillBufferWithLayerTransform() {
Alec Mouri1089aed2018-10-25 21:33:57 -0700896 renderengine::DisplaySettings settings;
897 settings.physicalDisplay = fullscreenRect();
898 // Here logical space is 2x2
899 settings.clip = Rect(2, 2);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800900 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700901
Sally Qi59a9f502021-10-12 18:53:23 +0000902 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700903
904 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800905 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700906 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
907 // Translate one pixel diagonally
908 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 -0800909 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700910 layer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
911 layer.alpha = 1.0f;
912
Sally Qi59a9f502021-10-12 18:53:23 +0000913 layers.push_back(layer);
Alec Mouri1089aed2018-10-25 21:33:57 -0700914
Alec Mouric0aae732021-01-12 13:32:18 -0800915 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800916}
Alec Mouri1089aed2018-10-25 21:33:57 -0700917
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800918template <typename SourceVariant>
919void RenderEngineTest::fillBufferLayerTransform() {
920 fillBufferWithLayerTransform<SourceVariant>();
Alec Mouri1089aed2018-10-25 21:33:57 -0700921 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 0, 0);
922 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
923 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
924 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
925 255, 0, 0, 255);
926}
927
928template <typename SourceVariant>
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800929void RenderEngineTest::fillBufferWithColorTransform() {
Alec Mouri1089aed2018-10-25 21:33:57 -0700930 renderengine::DisplaySettings settings;
931 settings.physicalDisplay = fullscreenRect();
932 settings.clip = Rect(1, 1);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800933 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700934
Sally Qi59a9f502021-10-12 18:53:23 +0000935 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700936
937 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800938 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700939 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800940 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700941 layer.alpha = 1.0f;
942
943 // construct a fake color matrix
944 // annihilate green and blue channels
KaiChieh Chuang436fc192020-09-07 13:48:42 +0800945 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
Alec Mouri1089aed2018-10-25 21:33:57 -0700946 // set red channel to red + green
947 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
948
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800949 layer.alpha = 1.0f;
950 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
951
Sally Qi59a9f502021-10-12 18:53:23 +0000952 layers.push_back(layer);
Alec Mouri1089aed2018-10-25 21:33:57 -0700953
Alec Mouric0aae732021-01-12 13:32:18 -0800954 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800955}
Alec Mouri1089aed2018-10-25 21:33:57 -0700956
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800957template <typename SourceVariant>
Sally Qi2019fd22021-11-22 10:19:04 -0800958void RenderEngineTest::fillBufferWithColorTransformAndSourceDataspace(
959 const ui::Dataspace sourceDataspace) {
960 renderengine::DisplaySettings settings;
961 settings.physicalDisplay = fullscreenRect();
962 settings.clip = Rect(1, 1);
963 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
964
965 std::vector<renderengine::LayerSettings> layers;
966
967 renderengine::LayerSettings layer;
Sally Qi2019fd22021-11-22 10:19:04 -0800968 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
969 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
Alec Mouric16974e2022-09-13 17:35:48 +0000970 layer.sourceDataspace = sourceDataspace;
Sally Qi2019fd22021-11-22 10:19:04 -0800971 layer.alpha = 1.0f;
972
973 // construct a fake color matrix
974 // annihilate green and blue channels
975 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
976 // set red channel to red + green
977 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
978
979 layer.alpha = 1.0f;
980 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
981
982 layers.push_back(layer);
983
984 invokeDraw(settings, layers);
985}
986
987template <typename SourceVariant>
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800988void RenderEngineTest::fillBufferColorTransform() {
989 fillBufferWithColorTransform<SourceVariant>();
KaiChieh Chuang436fc192020-09-07 13:48:42 +0800990 expectBufferColor(fullscreenRect(), 172, 0, 0, 255, 1);
991}
992
993template <typename SourceVariant>
Sally Qi2019fd22021-11-22 10:19:04 -0800994void RenderEngineTest::fillBufferColorTransformAndSourceDataspace() {
995 unordered_map<ui::Dataspace, ubyte4> dataspaceToColorMap;
Alec Mouric16974e2022-09-13 17:35:48 +0000996 dataspaceToColorMap[ui::Dataspace::V0_BT709] = {77, 0, 0, 255};
997 dataspaceToColorMap[ui::Dataspace::BT2020] = {101, 0, 0, 255};
998 dataspaceToColorMap[ui::Dataspace::ADOBE_RGB] = {75, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -0800999 ui::Dataspace customizedDataspace = static_cast<ui::Dataspace>(
1000 ui::Dataspace::STANDARD_BT709 | ui::Dataspace::TRANSFER_GAMMA2_2 |
1001 ui::Dataspace::RANGE_FULL);
Alec Mouric16974e2022-09-13 17:35:48 +00001002 dataspaceToColorMap[customizedDataspace] = {61, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -08001003 for (const auto& [sourceDataspace, color] : dataspaceToColorMap) {
1004 fillBufferWithColorTransformAndSourceDataspace<SourceVariant>(sourceDataspace);
1005 expectBufferColor(fullscreenRect(), color.r, color.g, color.b, color.a, 1);
1006 }
1007}
1008
1009template <typename SourceVariant>
1010void RenderEngineTest::fillBufferWithColorTransformAndOutputDataspace(
1011 const ui::Dataspace outputDataspace) {
1012 renderengine::DisplaySettings settings;
1013 settings.physicalDisplay = fullscreenRect();
1014 settings.clip = Rect(1, 1);
1015 settings.outputDataspace = outputDataspace;
1016
1017 std::vector<renderengine::LayerSettings> layers;
1018
1019 renderengine::LayerSettings layer;
1020 layer.sourceDataspace = ui::Dataspace::V0_SCRGB_LINEAR;
1021 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1022 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
1023 layer.alpha = 1.0f;
1024
1025 // construct a fake color matrix
1026 // annihilate green and blue channels
1027 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
1028 // set red channel to red + green
1029 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
1030
1031 layer.alpha = 1.0f;
1032 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1033
1034 layers.push_back(layer);
1035
1036 invokeDraw(settings, layers);
1037}
1038
1039template <typename SourceVariant>
1040void RenderEngineTest::fillBufferColorTransformAndOutputDataspace() {
1041 unordered_map<ui::Dataspace, ubyte4> dataspaceToColorMap;
Alec Mouric16974e2022-09-13 17:35:48 +00001042 dataspaceToColorMap[ui::Dataspace::V0_BT709] = {198, 0, 0, 255};
1043 dataspaceToColorMap[ui::Dataspace::BT2020] = {187, 0, 0, 255};
1044 dataspaceToColorMap[ui::Dataspace::ADOBE_RGB] = {192, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -08001045 ui::Dataspace customizedDataspace = static_cast<ui::Dataspace>(
1046 ui::Dataspace::STANDARD_BT709 | ui::Dataspace::TRANSFER_GAMMA2_6 |
1047 ui::Dataspace::RANGE_FULL);
Alec Mouric16974e2022-09-13 17:35:48 +00001048 dataspaceToColorMap[customizedDataspace] = {205, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -08001049 for (const auto& [outputDataspace, color] : dataspaceToColorMap) {
1050 fillBufferWithColorTransformAndOutputDataspace<SourceVariant>(outputDataspace);
1051 expectBufferColor(fullscreenRect(), color.r, color.g, color.b, color.a, 1);
1052 }
1053}
1054
1055template <typename SourceVariant>
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001056void RenderEngineTest::fillBufferWithColorTransformZeroLayerAlpha() {
1057 renderengine::DisplaySettings settings;
1058 settings.physicalDisplay = fullscreenRect();
1059 settings.clip = Rect(1, 1);
1060
Sally Qi59a9f502021-10-12 18:53:23 +00001061 std::vector<renderengine::LayerSettings> layers;
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001062
1063 renderengine::LayerSettings layer;
1064 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1065 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
1066 layer.alpha = 0;
1067
1068 // construct a fake color matrix
1069 // simple inverse color
1070 settings.colorTransform = mat4(-1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 1, 1, 1, 1);
1071
1072 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1073
Sally Qi59a9f502021-10-12 18:53:23 +00001074 layers.push_back(layer);
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001075
Alec Mouric0aae732021-01-12 13:32:18 -08001076 invokeDraw(settings, layers);
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001077}
1078
1079template <typename SourceVariant>
1080void RenderEngineTest::fillBufferColorTransformZeroLayerAlpha() {
1081 fillBufferWithColorTransformZeroLayerAlpha<SourceVariant>();
1082 expectBufferColor(fullscreenRect(), 0, 0, 0, 0);
1083}
1084
1085template <typename SourceVariant>
Alec Mouri7c94edb2018-12-03 21:23:26 -08001086void RenderEngineTest::fillRedBufferWithRoundedCorners() {
1087 renderengine::DisplaySettings settings;
1088 settings.physicalDisplay = fullscreenRect();
1089 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001090 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri7c94edb2018-12-03 21:23:26 -08001091
Sally Qi59a9f502021-10-12 18:53:23 +00001092 std::vector<renderengine::LayerSettings> layers;
Alec Mouri7c94edb2018-12-03 21:23:26 -08001093
1094 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001095 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri7c94edb2018-12-03 21:23:26 -08001096 layer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07001097 layer.geometry.roundedCornersRadius = {5.0f, 5.0f};
Alec Mouri7c94edb2018-12-03 21:23:26 -08001098 layer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
1099 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
1100 layer.alpha = 1.0f;
1101
Sally Qi59a9f502021-10-12 18:53:23 +00001102 layers.push_back(layer);
Alec Mouri7c94edb2018-12-03 21:23:26 -08001103
Alec Mouric0aae732021-01-12 13:32:18 -08001104 invokeDraw(settings, layers);
Alec Mouri7c94edb2018-12-03 21:23:26 -08001105}
1106
1107template <typename SourceVariant>
1108void RenderEngineTest::fillBufferWithRoundedCorners() {
1109 fillRedBufferWithRoundedCorners<SourceVariant>();
1110 // Corners should be ignored...
1111 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 0);
1112 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, 0, DEFAULT_DISPLAY_WIDTH, 1), 0, 0, 0, 0);
1113 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT - 1, 1, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
1114 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1,
1115 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1116 0, 0, 0, 0);
1117 // ...And the non-rounded portion should be red.
1118 // Other pixels may be anti-aliased, so let's not check those.
1119 expectBufferColor(Rect(5, 5, DEFAULT_DISPLAY_WIDTH - 5, DEFAULT_DISPLAY_HEIGHT - 5), 255, 0, 0,
1120 255);
1121}
1122
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001123template <typename SourceVariant>
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001124void RenderEngineTest::fillBufferAndBlurBackground() {
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001125 auto blurRadius = 50;
1126 auto center = DEFAULT_DISPLAY_WIDTH / 2;
1127
1128 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001129 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001130 settings.physicalDisplay = fullscreenRect();
1131 settings.clip = fullscreenRect();
1132
Sally Qi59a9f502021-10-12 18:53:23 +00001133 std::vector<renderengine::LayerSettings> layers;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001134
1135 renderengine::LayerSettings backgroundLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001136 backgroundLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001137 backgroundLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1138 SourceVariant::fillColor(backgroundLayer, 0.0f, 1.0f, 0.0f, this);
1139 backgroundLayer.alpha = 1.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001140 layers.emplace_back(backgroundLayer);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001141
1142 renderengine::LayerSettings leftLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001143 leftLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001144 leftLayer.geometry.boundaries =
1145 Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT).toFloatRect();
1146 SourceVariant::fillColor(leftLayer, 1.0f, 0.0f, 0.0f, this);
1147 leftLayer.alpha = 1.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001148 layers.emplace_back(leftLayer);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001149
1150 renderengine::LayerSettings blurLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001151 blurLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001152 blurLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1153 blurLayer.backgroundBlurRadius = blurRadius;
Derek Sollenbergerecb21462021-01-29 16:53:49 -05001154 SourceVariant::fillColor(blurLayer, 0.0f, 0.0f, 1.0f, this);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001155 blurLayer.alpha = 0;
Sally Qi59a9f502021-10-12 18:53:23 +00001156 layers.emplace_back(blurLayer);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001157
Alec Mouric0aae732021-01-12 13:32:18 -08001158 invokeDraw(settings, layers);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001159
Derek Sollenbergerecb21462021-01-29 16:53:49 -05001160 // solid color
1161 expectBufferColor(Rect(0, 0, 1, 1), 255, 0, 0, 255, 0 /* tolerance */);
1162
Derek Sollenbergerb3998372021-02-16 15:16:56 -05001163 if (mRE->supportsBackgroundBlur()) {
1164 // blurred color (downsampling should result in the center color being close to 128)
1165 expectBufferColor(Rect(center - 1, center - 5, center + 1, center + 5), 128, 128, 0, 255,
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001166 50 /* tolerance */);
Derek Sollenbergerb3998372021-02-16 15:16:56 -05001167 }
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001168}
1169
1170template <typename SourceVariant>
Alec Mourie8489fd2021-04-29 16:08:56 -07001171void RenderEngineTest::fillSmallLayerAndBlurBackground() {
1172 auto blurRadius = 50;
1173 renderengine::DisplaySettings settings;
1174 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1175 settings.physicalDisplay = fullscreenRect();
1176 settings.clip = fullscreenRect();
1177
Sally Qi59a9f502021-10-12 18:53:23 +00001178 std::vector<renderengine::LayerSettings> layers;
Alec Mourie8489fd2021-04-29 16:08:56 -07001179
1180 renderengine::LayerSettings backgroundLayer;
1181 backgroundLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1182 backgroundLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1183 SourceVariant::fillColor(backgroundLayer, 1.0f, 0.0f, 0.0f, this);
1184 backgroundLayer.alpha = 1.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001185 layers.push_back(backgroundLayer);
Alec Mourie8489fd2021-04-29 16:08:56 -07001186
1187 renderengine::LayerSettings blurLayer;
1188 blurLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1189 blurLayer.geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f);
1190 blurLayer.backgroundBlurRadius = blurRadius;
1191 SourceVariant::fillColor(blurLayer, 0.0f, 0.0f, 1.0f, this);
1192 blurLayer.alpha = 0;
Sally Qi59a9f502021-10-12 18:53:23 +00001193 layers.push_back(blurLayer);
Alec Mourie8489fd2021-04-29 16:08:56 -07001194
1195 invokeDraw(settings, layers);
1196
1197 // Give a generous tolerance - the blur rectangle is very small and this test is
1198 // mainly concerned with ensuring that there's no device failure.
1199 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT), 255, 0, 0, 255,
1200 40 /* tolerance */);
1201}
1202
1203template <typename SourceVariant>
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001204void RenderEngineTest::overlayCorners() {
1205 renderengine::DisplaySettings settings;
1206 settings.physicalDisplay = fullscreenRect();
1207 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001208 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001209
Sally Qi59a9f502021-10-12 18:53:23 +00001210 std::vector<renderengine::LayerSettings> layersFirst;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001211
1212 renderengine::LayerSettings layerOne;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001213 layerOne.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001214 layerOne.geometry.boundaries =
1215 FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH / 3.0, DEFAULT_DISPLAY_HEIGHT / 3.0);
1216 SourceVariant::fillColor(layerOne, 1.0f, 0.0f, 0.0f, this);
1217 layerOne.alpha = 0.2;
1218
Sally Qi59a9f502021-10-12 18:53:23 +00001219 layersFirst.push_back(layerOne);
Alec Mouric0aae732021-01-12 13:32:18 -08001220 invokeDraw(settings, layersFirst);
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001221 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3), 51, 0, 0, 51);
1222 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3 + 1, DEFAULT_DISPLAY_HEIGHT / 3 + 1,
1223 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1224 0, 0, 0, 0);
1225
Sally Qi59a9f502021-10-12 18:53:23 +00001226 std::vector<renderengine::LayerSettings> layersSecond;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001227 renderengine::LayerSettings layerTwo;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001228 layerTwo.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001229 layerTwo.geometry.boundaries =
1230 FloatRect(DEFAULT_DISPLAY_WIDTH / 3.0, DEFAULT_DISPLAY_HEIGHT / 3.0,
1231 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT);
1232 SourceVariant::fillColor(layerTwo, 0.0f, 1.0f, 0.0f, this);
1233 layerTwo.alpha = 1.0f;
1234
Sally Qi59a9f502021-10-12 18:53:23 +00001235 layersSecond.push_back(layerTwo);
Alec Mouric0aae732021-01-12 13:32:18 -08001236 invokeDraw(settings, layersSecond);
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001237
1238 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3), 0, 0, 0, 0);
1239 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3 + 1, DEFAULT_DISPLAY_HEIGHT / 3 + 1,
1240 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1241 0, 255, 0, 255);
1242}
1243
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001244void RenderEngineTest::fillRedBufferTextureTransform() {
1245 renderengine::DisplaySettings settings;
1246 settings.physicalDisplay = fullscreenRect();
1247 settings.clip = Rect(1, 1);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001248 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001249
Sally Qi59a9f502021-10-12 18:53:23 +00001250 std::vector<renderengine::LayerSettings> layers;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001251
1252 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001253 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001254 // Here will allocate a checker board texture, but transform texture
1255 // coordinates so that only the upper left is applied.
Alec Mouria90a5702021-04-16 16:36:21 +00001256 const auto buf = allocateSourceBuffer(2, 2);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001257 uint32_t texName;
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001258 RenderEngineTest::mRE->genTextures(1, &texName);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001259 this->mTexNames.push_back(texName);
1260
1261 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00001262 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1263 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001264 // Red top left, Green top right, Blue bottom left, Black bottom right
1265 pixels[0] = 255;
1266 pixels[1] = 0;
1267 pixels[2] = 0;
1268 pixels[3] = 255;
1269 pixels[4] = 0;
1270 pixels[5] = 255;
1271 pixels[6] = 0;
1272 pixels[7] = 255;
1273 pixels[8] = 0;
1274 pixels[9] = 0;
1275 pixels[10] = 255;
1276 pixels[11] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00001277 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001278
1279 layer.source.buffer.buffer = buf;
1280 layer.source.buffer.textureName = texName;
1281 // Transform coordinates to only be inside the red quadrant.
Alec Mouri4049b532021-10-15 20:59:33 -07001282 layer.source.buffer.textureTransform = mat4::scale(vec4(0.2f, 0.2f, 1.f, 1.f));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001283 layer.alpha = 1.0f;
1284 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1285
Sally Qi59a9f502021-10-12 18:53:23 +00001286 layers.push_back(layer);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001287
Alec Mouric0aae732021-01-12 13:32:18 -08001288 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001289}
1290
1291void RenderEngineTest::fillBufferTextureTransform() {
1292 fillRedBufferTextureTransform();
1293 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
1294}
1295
1296void RenderEngineTest::fillRedBufferWithPremultiplyAlpha() {
1297 renderengine::DisplaySettings settings;
1298 settings.physicalDisplay = fullscreenRect();
1299 // Here logical space is 1x1
1300 settings.clip = Rect(1, 1);
1301
Sally Qi59a9f502021-10-12 18:53:23 +00001302 std::vector<renderengine::LayerSettings> layers;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001303
1304 renderengine::LayerSettings layer;
Alec Mouria90a5702021-04-16 16:36:21 +00001305 const auto buf = allocateSourceBuffer(1, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001306 uint32_t texName;
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001307 RenderEngineTest::mRE->genTextures(1, &texName);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001308 this->mTexNames.push_back(texName);
1309
1310 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00001311 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1312 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001313 pixels[0] = 255;
1314 pixels[1] = 0;
1315 pixels[2] = 0;
1316 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00001317 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001318
1319 layer.source.buffer.buffer = buf;
1320 layer.source.buffer.textureName = texName;
1321 layer.source.buffer.usePremultipliedAlpha = true;
1322 layer.alpha = 0.5f;
1323 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1324
Sally Qi59a9f502021-10-12 18:53:23 +00001325 layers.push_back(layer);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001326
Alec Mouric0aae732021-01-12 13:32:18 -08001327 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001328}
1329
1330void RenderEngineTest::fillBufferWithPremultiplyAlpha() {
1331 fillRedBufferWithPremultiplyAlpha();
1332 expectBufferColor(fullscreenRect(), 128, 0, 0, 128);
1333}
1334
1335void RenderEngineTest::fillRedBufferWithoutPremultiplyAlpha() {
1336 renderengine::DisplaySettings settings;
1337 settings.physicalDisplay = fullscreenRect();
1338 // Here logical space is 1x1
1339 settings.clip = Rect(1, 1);
1340
Sally Qi59a9f502021-10-12 18:53:23 +00001341 std::vector<renderengine::LayerSettings> layers;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001342
1343 renderengine::LayerSettings layer;
Alec Mouria90a5702021-04-16 16:36:21 +00001344 const auto buf = allocateSourceBuffer(1, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001345 uint32_t texName;
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001346 RenderEngineTest::mRE->genTextures(1, &texName);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001347 this->mTexNames.push_back(texName);
1348
1349 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00001350 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1351 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001352 pixels[0] = 255;
1353 pixels[1] = 0;
1354 pixels[2] = 0;
1355 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00001356 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001357
1358 layer.source.buffer.buffer = buf;
1359 layer.source.buffer.textureName = texName;
1360 layer.source.buffer.usePremultipliedAlpha = false;
1361 layer.alpha = 0.5f;
1362 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1363
Sally Qi59a9f502021-10-12 18:53:23 +00001364 layers.push_back(layer);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001365
Alec Mouric0aae732021-01-12 13:32:18 -08001366 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001367}
1368
1369void RenderEngineTest::fillBufferWithoutPremultiplyAlpha() {
1370 fillRedBufferWithoutPremultiplyAlpha();
wukui16f3c0bb2020-08-05 20:35:29 +08001371 expectBufferColor(fullscreenRect(), 128, 0, 0, 128, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001372}
1373
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001374template <typename SourceVariant>
1375void RenderEngineTest::drawShadow(const renderengine::LayerSettings& castingLayer,
1376 const renderengine::ShadowSettings& shadow,
1377 const ubyte4& casterColor, const ubyte4& backgroundColor) {
1378 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001379 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001380 settings.physicalDisplay = fullscreenRect();
1381 settings.clip = fullscreenRect();
1382
Sally Qi59a9f502021-10-12 18:53:23 +00001383 std::vector<renderengine::LayerSettings> layers;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001384
1385 // add background layer
1386 renderengine::LayerSettings bgLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001387 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001388 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1389 ColorSourceVariant::fillColor(bgLayer, backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1390 backgroundColor.b / 255.0f, this);
1391 bgLayer.alpha = backgroundColor.a / 255.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001392 layers.push_back(bgLayer);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001393
1394 // add shadow layer
1395 renderengine::LayerSettings shadowLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001396 shadowLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001397 shadowLayer.geometry.boundaries = castingLayer.geometry.boundaries;
1398 shadowLayer.alpha = castingLayer.alpha;
1399 shadowLayer.shadow = shadow;
Sally Qi59a9f502021-10-12 18:53:23 +00001400 layers.push_back(shadowLayer);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001401
1402 // add layer casting the shadow
1403 renderengine::LayerSettings layer = castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001404 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001405 SourceVariant::fillColor(layer, casterColor.r / 255.0f, casterColor.g / 255.0f,
1406 casterColor.b / 255.0f, this);
Sally Qi59a9f502021-10-12 18:53:23 +00001407 layers.push_back(layer);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001408
Alec Mouric0aae732021-01-12 13:32:18 -08001409 invokeDraw(settings, layers);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001410}
1411
Alec Mouribd17b3b2020-12-17 11:08:30 -08001412void RenderEngineTest::drawShadowWithoutCaster(const FloatRect& castingBounds,
1413 const renderengine::ShadowSettings& shadow,
1414 const ubyte4& backgroundColor) {
1415 renderengine::DisplaySettings settings;
1416 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1417 settings.physicalDisplay = fullscreenRect();
1418 settings.clip = fullscreenRect();
1419
Sally Qi59a9f502021-10-12 18:53:23 +00001420 std::vector<renderengine::LayerSettings> layers;
Alec Mouribd17b3b2020-12-17 11:08:30 -08001421
1422 // add background layer
1423 renderengine::LayerSettings bgLayer;
1424 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1425 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1426 ColorSourceVariant::fillColor(bgLayer, backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1427 backgroundColor.b / 255.0f, this);
1428 bgLayer.alpha = backgroundColor.a / 255.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001429 layers.push_back(bgLayer);
Alec Mouribd17b3b2020-12-17 11:08:30 -08001430
1431 // add shadow layer
1432 renderengine::LayerSettings shadowLayer;
1433 shadowLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1434 shadowLayer.geometry.boundaries = castingBounds;
Derek Sollenbergerc31985e2021-05-18 16:38:17 -04001435 shadowLayer.skipContentDraw = true;
Alec Mouribd17b3b2020-12-17 11:08:30 -08001436 shadowLayer.alpha = 1.0f;
1437 ColorSourceVariant::fillColor(shadowLayer, 0, 0, 0, this);
1438 shadowLayer.shadow = shadow;
Sally Qi59a9f502021-10-12 18:53:23 +00001439 layers.push_back(shadowLayer);
Alec Mouribd17b3b2020-12-17 11:08:30 -08001440
Alec Mouric0aae732021-01-12 13:32:18 -08001441 invokeDraw(settings, layers);
Alec Mouribd17b3b2020-12-17 11:08:30 -08001442}
1443
Alec Mouri5a493722022-01-26 16:43:02 -08001444void RenderEngineTest::tonemap(ui::Dataspace sourceDataspace, std::function<vec3(vec3)> eotf,
1445 std::function<vec3(vec3, float)> scaleOotf) {
1446 constexpr int32_t kGreyLevels = 256;
1447
1448 const auto rect = Rect(0, 0, kGreyLevels, 1);
1449
1450 constexpr float kMaxLuminance = 750.f;
1451 constexpr float kCurrentLuminanceNits = 500.f;
1452 const renderengine::DisplaySettings display{
1453 .physicalDisplay = rect,
1454 .clip = rect,
1455 .maxLuminance = kMaxLuminance,
1456 .currentLuminanceNits = kCurrentLuminanceNits,
1457 .outputDataspace = ui::Dataspace::DISPLAY_P3,
1458 };
1459
1460 auto buf = std::make_shared<
1461 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07001462 ExternalTexture>(sp<GraphicBuffer>::make(kGreyLevels, 1,
1463 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1464 GRALLOC_USAGE_SW_READ_OFTEN |
1465 GRALLOC_USAGE_SW_WRITE_OFTEN |
1466 GRALLOC_USAGE_HW_RENDER |
1467 GRALLOC_USAGE_HW_TEXTURE,
1468 "input"),
Alec Mouri5a493722022-01-26 16:43:02 -08001469 *mRE,
1470 renderengine::impl::ExternalTexture::Usage::READABLE |
1471 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
1472 ASSERT_EQ(0, buf->getBuffer()->initCheck());
1473 {
1474 uint8_t* pixels;
1475 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1476 reinterpret_cast<void**>(&pixels));
1477
1478 uint8_t color = 0;
1479 for (int32_t j = 0; j < buf->getBuffer()->getHeight(); j++) {
1480 uint8_t* dest = pixels + (buf->getBuffer()->getStride() * j * 4);
1481 for (int32_t i = 0; i < buf->getBuffer()->getWidth(); i++) {
1482 dest[0] = color;
1483 dest[1] = color;
1484 dest[2] = color;
1485 dest[3] = 255;
1486 color++;
1487 dest += 4;
1488 }
1489 }
1490 buf->getBuffer()->unlock();
1491 }
1492
1493 mBuffer = std::make_shared<
1494 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07001495 ExternalTexture>(sp<GraphicBuffer>::make(kGreyLevels, 1,
1496 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1497 GRALLOC_USAGE_SW_READ_OFTEN |
1498 GRALLOC_USAGE_SW_WRITE_OFTEN |
1499 GRALLOC_USAGE_HW_RENDER |
1500 GRALLOC_USAGE_HW_TEXTURE,
1501 "output"),
Alec Mouri5a493722022-01-26 16:43:02 -08001502 *mRE,
1503 renderengine::impl::ExternalTexture::Usage::READABLE |
1504 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
1505 ASSERT_EQ(0, mBuffer->getBuffer()->initCheck());
1506
1507 const renderengine::LayerSettings layer{.geometry.boundaries = rect.toFloatRect(),
1508 .source =
1509 renderengine::PixelSource{
1510 .buffer =
1511 renderengine::Buffer{
1512 .buffer =
1513 std::move(buf),
1514 .usePremultipliedAlpha =
1515 true,
1516 },
1517 },
1518 .alpha = 1.0f,
1519 .sourceDataspace = sourceDataspace};
1520
1521 std::vector<renderengine::LayerSettings> layers{layer};
1522 invokeDraw(display, layers);
1523
1524 ColorSpace displayP3 = ColorSpace::DisplayP3();
1525 ColorSpace bt2020 = ColorSpace::BT2020();
1526
1527 tonemap::Metadata metadata{.displayMaxLuminance = 750.0f};
1528
1529 auto generator = [=](Point location) {
1530 const double normColor = static_cast<double>(location.x) / (kGreyLevels - 1);
1531 const vec3 rgb = vec3(normColor, normColor, normColor);
1532
1533 const vec3 linearRGB = eotf(rgb);
1534
1535 const vec3 xyz = bt2020.getRGBtoXYZ() * linearRGB;
1536
1537 const vec3 scaledXYZ = scaleOotf(xyz, kCurrentLuminanceNits);
Alec Mouri196b0f22022-03-04 22:13:48 +00001538 const auto gains =
Alec Mouri5a493722022-01-26 16:43:02 -08001539 tonemap::getToneMapper()
1540 ->lookupTonemapGain(static_cast<aidl::android::hardware::graphics::common::
1541 Dataspace>(sourceDataspace),
1542 static_cast<aidl::android::hardware::graphics::common::
1543 Dataspace>(
1544 ui::Dataspace::DISPLAY_P3),
Alec Mouri196b0f22022-03-04 22:13:48 +00001545 {tonemap::
1546 Color{.linearRGB =
1547 scaleOotf(linearRGB,
1548 kCurrentLuminanceNits),
1549 .xyz = scaledXYZ}},
Alec Mouri5a493722022-01-26 16:43:02 -08001550 metadata);
Alec Mouri196b0f22022-03-04 22:13:48 +00001551 EXPECT_EQ(1, gains.size());
1552 const double gain = gains.front();
Alec Mouri5a493722022-01-26 16:43:02 -08001553 const vec3 normalizedXYZ = scaledXYZ * gain / metadata.displayMaxLuminance;
1554
1555 const vec3 targetRGB = OETF_sRGB(displayP3.getXYZtoRGB() * normalizedXYZ) * 255;
1556 return ubyte4(static_cast<uint8_t>(targetRGB.r), static_cast<uint8_t>(targetRGB.g),
1557 static_cast<uint8_t>(targetRGB.b), 255);
1558 };
1559
1560 expectBufferColor(Rect(kGreyLevels, 1), generator, 2);
1561}
1562
Ian Elliott32f9e692022-11-22 15:30:29 -07001563#ifdef RE_SKIAVK
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001564INSTANTIATE_TEST_SUITE_P(PerRenderEngineType, RenderEngineTest,
Alec Mouric16974e2022-09-13 17:35:48 +00001565 testing::Values(std::make_shared<SkiaGLESRenderEngineFactory>(),
Ian Elliott1f0911e2022-09-09 16:31:47 -06001566 std::make_shared<SkiaGLESCMRenderEngineFactory>(),
1567 std::make_shared<SkiaVkRenderEngineFactory>(),
1568 std::make_shared<SkiaVkCMRenderEngineFactory>()));
Ian Elliott32f9e692022-11-22 15:30:29 -07001569#else // RE_SKIAVK
1570INSTANTIATE_TEST_SUITE_P(PerRenderEngineType, RenderEngineTest,
1571 testing::Values(std::make_shared<SkiaGLESRenderEngineFactory>(),
1572 std::make_shared<SkiaGLESCMRenderEngineFactory>()));
1573#endif // RE_SKIAVK
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001574
1575TEST_P(RenderEngineTest, drawLayers_noLayersToDraw) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001576 if (!GetParam()->typeSupported()) {
1577 GTEST_SKIP();
1578 }
Alec Mouric0aae732021-01-12 13:32:18 -08001579 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001580 drawEmptyLayers();
1581}
1582
Sally Qi1fed86e2022-06-23 15:33:52 -07001583TEST_P(RenderEngineTest, drawLayers_fillRedBufferAndEmptyBuffer) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001584 if (!GetParam()->typeSupported()) {
1585 GTEST_SKIP();
1586 }
Sally Qi1fed86e2022-06-23 15:33:52 -07001587 initializeRenderEngine();
1588 renderengine::DisplaySettings settings;
1589 settings.physicalDisplay = fullscreenRect();
1590 settings.clip = fullscreenRect();
1591 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1592
1593 // add a red layer
1594 renderengine::LayerSettings layerOne{
1595 .geometry.boundaries = fullscreenRect().toFloatRect(),
1596 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
1597 .alpha = 1.f,
1598 };
1599
1600 std::vector<renderengine::LayerSettings> layersFirst{layerOne};
1601 invokeDraw(settings, layersFirst);
1602 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
1603
1604 // re-draw with an empty layer above it, and we get a transparent black one
1605 std::vector<renderengine::LayerSettings> layersSecond;
1606 invokeDraw(settings, layersSecond);
1607 expectBufferColor(fullscreenRect(), 0, 0, 0, 0);
1608}
1609
Ana Krulec07b98df2021-01-07 14:38:40 -08001610TEST_P(RenderEngineTest, drawLayers_withoutBuffers_withColorTransform) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001611 if (!GetParam()->typeSupported()) {
1612 GTEST_SKIP();
1613 }
Alec Mouria90a5702021-04-16 16:36:21 +00001614 initializeRenderEngine();
Ana Krulec07b98df2021-01-07 14:38:40 -08001615
1616 renderengine::DisplaySettings settings;
1617 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1618 settings.physicalDisplay = fullscreenRect();
1619 settings.clip = fullscreenRect();
1620
1621 // 255, 255, 255, 255 is full opaque white.
Alec Mouri4049b532021-10-15 20:59:33 -07001622 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
1623 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Ana Krulec07b98df2021-01-07 14:38:40 -08001624 // Create layer with given color.
1625 renderengine::LayerSettings bgLayer;
1626 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1627 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1628 bgLayer.source.solidColor = half3(backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1629 backgroundColor.b / 255.0f);
1630 bgLayer.alpha = backgroundColor.a / 255.0f;
1631 // Transform the red color.
1632 bgLayer.colorTransform = mat4(-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
1633
Sally Qi59a9f502021-10-12 18:53:23 +00001634 std::vector<renderengine::LayerSettings> layers;
1635 layers.push_back(bgLayer);
Ana Krulec07b98df2021-01-07 14:38:40 -08001636
Alec Mouric0aae732021-01-12 13:32:18 -08001637 invokeDraw(settings, layers);
Ana Krulec07b98df2021-01-07 14:38:40 -08001638
1639 // Expect to see full opaque pixel (with inverted red from the transform).
Alec Mouric0aae732021-01-12 13:32:18 -08001640 expectBufferColor(Rect(0, 0, 10, 10), 0.f, backgroundColor.g, backgroundColor.b,
Ana Krulec07b98df2021-01-07 14:38:40 -08001641 backgroundColor.a);
1642}
1643
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001644TEST_P(RenderEngineTest, drawLayers_nullOutputBuffer) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001645 if (!GetParam()->typeSupported()) {
1646 GTEST_SKIP();
1647 }
Alec Mouric0aae732021-01-12 13:32:18 -08001648 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001649
Alec Mourid43ccab2019-03-13 12:23:45 -07001650 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001651 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Sally Qi59a9f502021-10-12 18:53:23 +00001652 std::vector<renderengine::LayerSettings> layers;
Alec Mourid43ccab2019-03-13 12:23:45 -07001653 renderengine::LayerSettings layer;
1654 layer.geometry.boundaries = fullscreenRect().toFloatRect();
1655 BufferSourceVariant<ForceOpaqueBufferVariant>::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
Sally Qi59a9f502021-10-12 18:53:23 +00001656 layers.push_back(layer);
Patrick Williams2e9748f2022-08-09 22:48:18 +00001657 ftl::Future<FenceResult> future =
Sally Qi4cabdd02021-08-05 16:45:57 -07001658 mRE->drawLayers(settings, layers, nullptr, true, base::unique_fd());
Alec Mourid43ccab2019-03-13 12:23:45 -07001659
Patrick Williams2e9748f2022-08-09 22:48:18 +00001660 ASSERT_TRUE(future.valid());
1661 auto result = future.get();
1662 ASSERT_FALSE(result.ok());
1663 ASSERT_EQ(BAD_VALUE, result.error());
Alec Mourid43ccab2019-03-13 12:23:45 -07001664}
1665
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001666TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001667 if (!GetParam()->typeSupported()) {
1668 GTEST_SKIP();
1669 }
Alec Mouric0aae732021-01-12 13:32:18 -08001670 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001671 fillRedBuffer<ColorSourceVariant>();
1672}
1673
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001674TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001675 if (!GetParam()->typeSupported()) {
1676 GTEST_SKIP();
1677 }
Alec Mouric0aae732021-01-12 13:32:18 -08001678 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001679 fillGreenBuffer<ColorSourceVariant>();
1680}
1681
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001682TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001683 if (!GetParam()->typeSupported()) {
1684 GTEST_SKIP();
1685 }
Alec Mouric0aae732021-01-12 13:32:18 -08001686 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001687 fillBlueBuffer<ColorSourceVariant>();
1688}
1689
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001690TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001691 if (!GetParam()->typeSupported()) {
1692 GTEST_SKIP();
1693 }
Alec Mouric0aae732021-01-12 13:32:18 -08001694 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001695 fillRedTransparentBuffer<ColorSourceVariant>();
1696}
1697
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001698TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001699 if (!GetParam()->typeSupported()) {
1700 GTEST_SKIP();
1701 }
Alec Mouric0aae732021-01-12 13:32:18 -08001702 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001703 fillBufferPhysicalOffset<ColorSourceVariant>();
1704}
1705
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001706TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001707 if (!GetParam()->typeSupported()) {
1708 GTEST_SKIP();
1709 }
Alec Mouric0aae732021-01-12 13:32:18 -08001710 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001711 fillBufferCheckersRotate0<ColorSourceVariant>();
1712}
1713
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001714TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001715 if (!GetParam()->typeSupported()) {
1716 GTEST_SKIP();
1717 }
Alec Mouric0aae732021-01-12 13:32:18 -08001718 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001719 fillBufferCheckersRotate90<ColorSourceVariant>();
1720}
1721
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001722TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001723 if (!GetParam()->typeSupported()) {
1724 GTEST_SKIP();
1725 }
Alec Mouric0aae732021-01-12 13:32:18 -08001726 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001727 fillBufferCheckersRotate180<ColorSourceVariant>();
1728}
1729
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001730TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001731 if (!GetParam()->typeSupported()) {
1732 GTEST_SKIP();
1733 }
Alec Mouric0aae732021-01-12 13:32:18 -08001734 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001735 fillBufferCheckersRotate270<ColorSourceVariant>();
1736}
1737
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001738TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001739 if (!GetParam()->typeSupported()) {
1740 GTEST_SKIP();
1741 }
Alec Mouric0aae732021-01-12 13:32:18 -08001742 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001743 fillBufferLayerTransform<ColorSourceVariant>();
1744}
1745
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001746TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001747 if (!GetParam()->typeSupported()) {
1748 GTEST_SKIP();
1749 }
Alec Mouric0aae732021-01-12 13:32:18 -08001750 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08001751 fillBufferColorTransform<ColorSourceVariant>();
1752}
1753
Sally Qi2019fd22021-11-22 10:19:04 -08001754TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_sourceDataspace) {
1755 const auto& renderEngineFactory = GetParam();
1756 // skip for non color management
Ian Elliott1f0911e2022-09-09 16:31:47 -06001757 if (!renderEngineFactory->typeSupported() || !renderEngineFactory->useColorManagement()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001758 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001759 }
1760
1761 initializeRenderEngine();
1762 fillBufferColorTransformAndSourceDataspace<ColorSourceVariant>();
1763}
1764
1765TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_outputDataspace) {
1766 const auto& renderEngineFactory = GetParam();
1767 // skip for non color management
Ian Elliott1f0911e2022-09-09 16:31:47 -06001768 if (!renderEngineFactory->typeSupported() || !renderEngineFactory->useColorManagement()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001769 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001770 }
1771
1772 initializeRenderEngine();
1773 fillBufferColorTransformAndOutputDataspace<ColorSourceVariant>();
1774}
1775
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001776TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001777 if (!GetParam()->typeSupported()) {
1778 GTEST_SKIP();
1779 }
Alec Mouric0aae732021-01-12 13:32:18 -08001780 initializeRenderEngine();
Alec Mouri7c94edb2018-12-03 21:23:26 -08001781 fillBufferWithRoundedCorners<ColorSourceVariant>();
1782}
1783
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001784TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001785 if (!GetParam()->typeSupported()) {
1786 GTEST_SKIP();
1787 }
Alec Mouric0aae732021-01-12 13:32:18 -08001788 initializeRenderEngine();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001789 fillBufferColorTransformZeroLayerAlpha<ColorSourceVariant>();
1790}
1791
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001792TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001793 if (!GetParam()->typeSupported()) {
1794 GTEST_SKIP();
1795 }
Alec Mouric0aae732021-01-12 13:32:18 -08001796 initializeRenderEngine();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001797 fillBufferAndBlurBackground<ColorSourceVariant>();
1798}
1799
Alec Mourie8489fd2021-04-29 16:08:56 -07001800TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001801 if (!GetParam()->typeSupported()) {
1802 GTEST_SKIP();
1803 }
Alec Mourie8489fd2021-04-29 16:08:56 -07001804 initializeRenderEngine();
1805 fillSmallLayerAndBlurBackground<ColorSourceVariant>();
1806}
1807
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001808TEST_P(RenderEngineTest, drawLayers_overlayCorners_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001809 if (!GetParam()->typeSupported()) {
1810 GTEST_SKIP();
1811 }
Alec Mouric0aae732021-01-12 13:32:18 -08001812 initializeRenderEngine();
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001813 overlayCorners<ColorSourceVariant>();
1814}
1815
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001816TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001817 if (!GetParam()->typeSupported()) {
1818 GTEST_SKIP();
1819 }
Alec Mouric0aae732021-01-12 13:32:18 -08001820 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001821 fillRedBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1822}
1823
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001824TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001825 if (!GetParam()->typeSupported()) {
1826 GTEST_SKIP();
1827 }
Alec Mouric0aae732021-01-12 13:32:18 -08001828 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001829 fillGreenBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1830}
1831
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001832TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001833 if (!GetParam()->typeSupported()) {
1834 GTEST_SKIP();
1835 }
Alec Mouric0aae732021-01-12 13:32:18 -08001836 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001837 fillBlueBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1838}
1839
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001840TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001841 if (!GetParam()->typeSupported()) {
1842 GTEST_SKIP();
1843 }
Alec Mouric0aae732021-01-12 13:32:18 -08001844 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001845 fillRedTransparentBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1846}
1847
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001848TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001849 if (!GetParam()->typeSupported()) {
1850 GTEST_SKIP();
1851 }
Alec Mouric0aae732021-01-12 13:32:18 -08001852 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001853 fillBufferPhysicalOffset<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1854}
1855
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001856TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001857 if (!GetParam()->typeSupported()) {
1858 GTEST_SKIP();
1859 }
Alec Mouric0aae732021-01-12 13:32:18 -08001860 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001861 fillBufferCheckersRotate0<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1862}
1863
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001864TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001865 if (!GetParam()->typeSupported()) {
1866 GTEST_SKIP();
1867 }
Alec Mouric0aae732021-01-12 13:32:18 -08001868 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001869 fillBufferCheckersRotate90<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1870}
1871
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001872TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001873 if (!GetParam()->typeSupported()) {
1874 GTEST_SKIP();
1875 }
Alec Mouric0aae732021-01-12 13:32:18 -08001876 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001877 fillBufferCheckersRotate180<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1878}
1879
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001880TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001881 if (!GetParam()->typeSupported()) {
1882 GTEST_SKIP();
1883 }
Alec Mouric0aae732021-01-12 13:32:18 -08001884 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001885 fillBufferCheckersRotate270<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1886}
1887
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001888TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001889 if (!GetParam()->typeSupported()) {
1890 GTEST_SKIP();
1891 }
Alec Mouric0aae732021-01-12 13:32:18 -08001892 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001893 fillBufferLayerTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1894}
1895
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001896TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001897 if (!GetParam()->typeSupported()) {
1898 GTEST_SKIP();
1899 }
Alec Mouric0aae732021-01-12 13:32:18 -08001900 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08001901 fillBufferColorTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1902}
1903
Sally Qi2019fd22021-11-22 10:19:04 -08001904TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndSourceDataspace_opaqueBufferSource) {
1905 const auto& renderEngineFactory = GetParam();
1906 // skip for non color management
Ian Elliott1f0911e2022-09-09 16:31:47 -06001907 if (!renderEngineFactory->typeSupported() || !renderEngineFactory->useColorManagement()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001908 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001909 }
1910
1911 initializeRenderEngine();
1912 fillBufferColorTransformAndSourceDataspace<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1913}
1914
1915TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndOutputDataspace_opaqueBufferSource) {
1916 const auto& renderEngineFactory = GetParam();
1917 // skip for non color management
Ian Elliott1f0911e2022-09-09 16:31:47 -06001918 if (!renderEngineFactory->typeSupported() || !renderEngineFactory->useColorManagement()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001919 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001920 }
1921
1922 initializeRenderEngine();
1923 fillBufferColorTransformAndOutputDataspace<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1924}
1925
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001926TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001927 if (!GetParam()->typeSupported()) {
1928 GTEST_SKIP();
1929 }
Alec Mouric0aae732021-01-12 13:32:18 -08001930 initializeRenderEngine();
Alec Mouri7c94edb2018-12-03 21:23:26 -08001931 fillBufferWithRoundedCorners<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1932}
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001933
Alec Mouric0aae732021-01-12 13:32:18 -08001934TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001935 if (!GetParam()->typeSupported()) {
1936 GTEST_SKIP();
1937 }
Alec Mouric0aae732021-01-12 13:32:18 -08001938 initializeRenderEngine();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001939 fillBufferColorTransformZeroLayerAlpha<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1940}
Alec Mouri7c94edb2018-12-03 21:23:26 -08001941
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001942TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001943 if (!GetParam()->typeSupported()) {
1944 GTEST_SKIP();
1945 }
Alec Mouric0aae732021-01-12 13:32:18 -08001946 initializeRenderEngine();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001947 fillBufferAndBlurBackground<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1948}
1949
Alec Mourie8489fd2021-04-29 16:08:56 -07001950TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001951 if (!GetParam()->typeSupported()) {
1952 GTEST_SKIP();
1953 }
Alec Mourie8489fd2021-04-29 16:08:56 -07001954 initializeRenderEngine();
1955 fillSmallLayerAndBlurBackground<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1956}
1957
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001958TEST_P(RenderEngineTest, drawLayers_overlayCorners_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001959 if (!GetParam()->typeSupported()) {
1960 GTEST_SKIP();
1961 }
Alec Mouric0aae732021-01-12 13:32:18 -08001962 initializeRenderEngine();
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001963 overlayCorners<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1964}
1965
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001966TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001967 if (!GetParam()->typeSupported()) {
1968 GTEST_SKIP();
1969 }
Alec Mouric0aae732021-01-12 13:32:18 -08001970 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001971 fillRedBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1972}
1973
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001974TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001975 if (!GetParam()->typeSupported()) {
1976 GTEST_SKIP();
1977 }
Alec Mouric0aae732021-01-12 13:32:18 -08001978 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001979 fillGreenBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1980}
1981
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001982TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001983 if (!GetParam()->typeSupported()) {
1984 GTEST_SKIP();
1985 }
Alec Mouric0aae732021-01-12 13:32:18 -08001986 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001987 fillBlueBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1988}
1989
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001990TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001991 if (!GetParam()->typeSupported()) {
1992 GTEST_SKIP();
1993 }
Alec Mouric0aae732021-01-12 13:32:18 -08001994 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001995 fillRedTransparentBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1996}
1997
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001998TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001999 if (!GetParam()->typeSupported()) {
2000 GTEST_SKIP();
2001 }
Alec Mouric0aae732021-01-12 13:32:18 -08002002 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002003 fillBufferPhysicalOffset<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2004}
2005
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002006TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002007 if (!GetParam()->typeSupported()) {
2008 GTEST_SKIP();
2009 }
Alec Mouric0aae732021-01-12 13:32:18 -08002010 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002011 fillBufferCheckersRotate0<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2012}
2013
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002014TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002015 if (!GetParam()->typeSupported()) {
2016 GTEST_SKIP();
2017 }
Alec Mouric0aae732021-01-12 13:32:18 -08002018 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002019 fillBufferCheckersRotate90<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2020}
2021
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002022TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002023 if (!GetParam()->typeSupported()) {
2024 GTEST_SKIP();
2025 }
Alec Mouric0aae732021-01-12 13:32:18 -08002026 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002027 fillBufferCheckersRotate180<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2028}
2029
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002030TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002031 if (!GetParam()->typeSupported()) {
2032 GTEST_SKIP();
2033 }
Alec Mouric0aae732021-01-12 13:32:18 -08002034 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002035 fillBufferCheckersRotate270<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2036}
2037
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002038TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002039 if (!GetParam()->typeSupported()) {
2040 GTEST_SKIP();
2041 }
Alec Mouric0aae732021-01-12 13:32:18 -08002042 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002043 fillBufferLayerTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2044}
2045
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002046TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002047 if (!GetParam()->typeSupported()) {
2048 GTEST_SKIP();
2049 }
Alec Mouric0aae732021-01-12 13:32:18 -08002050 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08002051 fillBufferColorTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2052}
2053
Sally Qi2019fd22021-11-22 10:19:04 -08002054TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndSourceDataspace_bufferSource) {
2055 const auto& renderEngineFactory = GetParam();
2056 // skip for non color management
Ian Elliott1f0911e2022-09-09 16:31:47 -06002057 if (!renderEngineFactory->typeSupported() || !renderEngineFactory->useColorManagement()) {
Alec Mouric16974e2022-09-13 17:35:48 +00002058 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08002059 }
2060
2061 initializeRenderEngine();
2062 fillBufferColorTransformAndSourceDataspace<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2063}
2064
2065TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndOutputDataspace_bufferSource) {
2066 const auto& renderEngineFactory = GetParam();
2067 // skip for non color management
Ian Elliott1f0911e2022-09-09 16:31:47 -06002068 if (!renderEngineFactory->typeSupported() || !renderEngineFactory->useColorManagement()) {
Alec Mouric16974e2022-09-13 17:35:48 +00002069 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08002070 }
2071
2072 initializeRenderEngine();
2073 fillBufferColorTransformAndOutputDataspace<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2074}
2075
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002076TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002077 if (!GetParam()->typeSupported()) {
2078 GTEST_SKIP();
2079 }
Alec Mouric0aae732021-01-12 13:32:18 -08002080 initializeRenderEngine();
Alec Mouri7c94edb2018-12-03 21:23:26 -08002081 fillBufferWithRoundedCorners<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2082}
2083
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08002084TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002085 if (!GetParam()->typeSupported()) {
2086 GTEST_SKIP();
2087 }
Alec Mouric0aae732021-01-12 13:32:18 -08002088 initializeRenderEngine();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08002089 fillBufferColorTransformZeroLayerAlpha<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2090}
2091
Nathaniel Nifong53494f32021-04-30 14:05:39 -04002092TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002093 if (!GetParam()->typeSupported()) {
2094 GTEST_SKIP();
2095 }
Alec Mouric0aae732021-01-12 13:32:18 -08002096 initializeRenderEngine();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08002097 fillBufferAndBlurBackground<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2098}
2099
Alec Mourie8489fd2021-04-29 16:08:56 -07002100TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002101 if (!GetParam()->typeSupported()) {
2102 GTEST_SKIP();
2103 }
Alec Mourie8489fd2021-04-29 16:08:56 -07002104 initializeRenderEngine();
2105 fillSmallLayerAndBlurBackground<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2106}
2107
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002108TEST_P(RenderEngineTest, drawLayers_overlayCorners_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002109 if (!GetParam()->typeSupported()) {
2110 GTEST_SKIP();
2111 }
Alec Mouric0aae732021-01-12 13:32:18 -08002112 initializeRenderEngine();
Alec Mourie7d1d4a2019-02-05 01:13:46 +00002113 overlayCorners<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2114}
2115
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002116TEST_P(RenderEngineTest, drawLayers_fillBufferTextureTransform) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002117 if (!GetParam()->typeSupported()) {
2118 GTEST_SKIP();
2119 }
Alec Mouric0aae732021-01-12 13:32:18 -08002120 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002121 fillBufferTextureTransform();
2122}
2123
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002124TEST_P(RenderEngineTest, drawLayers_fillBuffer_premultipliesAlpha) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002125 if (!GetParam()->typeSupported()) {
2126 GTEST_SKIP();
2127 }
Alec Mouric0aae732021-01-12 13:32:18 -08002128 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002129 fillBufferWithPremultiplyAlpha();
2130}
2131
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002132TEST_P(RenderEngineTest, drawLayers_fillBuffer_withoutPremultiplyingAlpha) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002133 if (!GetParam()->typeSupported()) {
2134 GTEST_SKIP();
2135 }
Alec Mouric0aae732021-01-12 13:32:18 -08002136 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002137 fillBufferWithoutPremultiplyAlpha();
2138}
2139
Alec Mouribd17b3b2020-12-17 11:08:30 -08002140TEST_P(RenderEngineTest, drawLayers_fillShadow_castsWithoutCasterLayer) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002141 if (!GetParam()->typeSupported()) {
2142 GTEST_SKIP();
2143 }
Alec Mouric0aae732021-01-12 13:32:18 -08002144 initializeRenderEngine();
Alec Mouribd17b3b2020-12-17 11:08:30 -08002145
Alec Mouri4049b532021-10-15 20:59:33 -07002146 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2147 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Alec Mouribd17b3b2020-12-17 11:08:30 -08002148 const float shadowLength = 5.0f;
2149 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2150 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2151 renderengine::ShadowSettings settings =
2152 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2153 false /* casterIsTranslucent */);
2154
2155 drawShadowWithoutCaster(casterBounds.toFloatRect(), settings, backgroundColor);
2156 expectShadowColorWithoutCaster(casterBounds.toFloatRect(), settings, backgroundColor);
2157}
2158
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002159TEST_P(RenderEngineTest, drawLayers_fillShadow_casterLayerMinSize) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002160 if (!GetParam()->typeSupported()) {
2161 GTEST_SKIP();
2162 }
Alec Mouric0aae732021-01-12 13:32:18 -08002163 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002164
Alec Mouri4049b532021-10-15 20:59:33 -07002165 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2166 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2167 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2168 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002169 const float shadowLength = 5.0f;
2170 Rect casterBounds(1, 1);
2171 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2172 renderengine::LayerSettings castingLayer;
2173 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2174 castingLayer.alpha = 1.0f;
2175 renderengine::ShadowSettings settings =
2176 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2177 false /* casterIsTranslucent */);
2178
2179 drawShadow<ColorSourceVariant>(castingLayer, settings, casterColor, backgroundColor);
2180 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2181}
2182
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002183TEST_P(RenderEngineTest, drawLayers_fillShadow_casterColorLayer) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002184 if (!GetParam()->typeSupported()) {
2185 GTEST_SKIP();
2186 }
Alec Mouric0aae732021-01-12 13:32:18 -08002187 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002188
Alec Mouri4049b532021-10-15 20:59:33 -07002189 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2190 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2191 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2192 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002193 const float shadowLength = 5.0f;
2194 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2195 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2196 renderengine::LayerSettings castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002197 castingLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002198 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2199 castingLayer.alpha = 1.0f;
2200 renderengine::ShadowSettings settings =
2201 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2202 false /* casterIsTranslucent */);
2203
2204 drawShadow<ColorSourceVariant>(castingLayer, settings, casterColor, backgroundColor);
2205 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2206}
2207
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002208TEST_P(RenderEngineTest, drawLayers_fillShadow_casterOpaqueBufferLayer) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002209 if (!GetParam()->typeSupported()) {
2210 GTEST_SKIP();
2211 }
Alec Mouric0aae732021-01-12 13:32:18 -08002212 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002213
Alec Mouri4049b532021-10-15 20:59:33 -07002214 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2215 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2216 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2217 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002218 const float shadowLength = 5.0f;
2219 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2220 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2221 renderengine::LayerSettings castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002222 castingLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002223 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2224 castingLayer.alpha = 1.0f;
2225 renderengine::ShadowSettings settings =
2226 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2227 false /* casterIsTranslucent */);
2228
2229 drawShadow<BufferSourceVariant<ForceOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2230 backgroundColor);
2231 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2232}
2233
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002234TEST_P(RenderEngineTest, drawLayers_fillShadow_casterWithRoundedCorner) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002235 if (!GetParam()->typeSupported()) {
2236 GTEST_SKIP();
2237 }
Alec Mouric0aae732021-01-12 13:32:18 -08002238 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002239
Alec Mouri4049b532021-10-15 20:59:33 -07002240 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2241 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2242 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2243 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002244 const float shadowLength = 5.0f;
2245 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2246 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2247 renderengine::LayerSettings castingLayer;
2248 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002249 castingLayer.geometry.roundedCornersRadius = {3.0f, 3.0f};
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002250 castingLayer.geometry.roundedCornersCrop = casterBounds.toFloatRect();
2251 castingLayer.alpha = 1.0f;
2252 renderengine::ShadowSettings settings =
2253 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2254 false /* casterIsTranslucent */);
2255
2256 drawShadow<BufferSourceVariant<ForceOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2257 backgroundColor);
2258 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2259}
2260
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002261TEST_P(RenderEngineTest, drawLayers_fillShadow_translucentCasterWithAlpha) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002262 if (!GetParam()->typeSupported()) {
2263 GTEST_SKIP();
2264 }
Alec Mouric0aae732021-01-12 13:32:18 -08002265 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002266
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002267 const ubyte4 casterColor(255, 0, 0, 255);
2268 const ubyte4 backgroundColor(255, 255, 255, 255);
2269 const float shadowLength = 5.0f;
2270 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2271 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2272 renderengine::LayerSettings castingLayer;
2273 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2274 castingLayer.alpha = 0.5f;
2275 renderengine::ShadowSettings settings =
2276 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2277 true /* casterIsTranslucent */);
2278
2279 drawShadow<BufferSourceVariant<RelaxOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2280 backgroundColor);
2281
2282 // verify only the background since the shadow will draw behind the caster
2283 const float shadowInset = settings.length * -1.0f;
2284 const Rect casterWithShadow =
2285 Rect(casterBounds).inset(shadowInset, shadowInset, shadowInset, shadowInset);
2286 const Region backgroundRegion = Region(fullscreenRect()).subtractSelf(casterWithShadow);
2287 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
2288 backgroundColor.a);
2289}
2290
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002291TEST_P(RenderEngineTest, cleanupPostRender_cleansUpOnce) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002292 if (!GetParam()->typeSupported()) {
2293 GTEST_SKIP();
2294 }
Alec Mouric0aae732021-01-12 13:32:18 -08002295 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002296
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002297 renderengine::DisplaySettings settings;
2298 settings.physicalDisplay = fullscreenRect();
2299 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002300 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002301
Sally Qi59a9f502021-10-12 18:53:23 +00002302 std::vector<renderengine::LayerSettings> layers;
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002303 renderengine::LayerSettings layer;
2304 layer.geometry.boundaries = fullscreenRect().toFloatRect();
2305 BufferSourceVariant<ForceOpaqueBufferVariant>::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
2306 layer.alpha = 1.0;
Sally Qi59a9f502021-10-12 18:53:23 +00002307 layers.push_back(layer);
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002308
Patrick Williams2e9748f2022-08-09 22:48:18 +00002309 ftl::Future<FenceResult> futureOne =
Sally Qi4cabdd02021-08-05 16:45:57 -07002310 mRE->drawLayers(settings, layers, mBuffer, true, base::unique_fd());
Patrick Williams2e9748f2022-08-09 22:48:18 +00002311 ASSERT_TRUE(futureOne.valid());
2312 auto resultOne = futureOne.get();
2313 ASSERT_TRUE(resultOne.ok());
2314 auto fenceOne = resultOne.value();
Sally Qi4cabdd02021-08-05 16:45:57 -07002315
Patrick Williams2e9748f2022-08-09 22:48:18 +00002316 ftl::Future<FenceResult> futureTwo =
2317 mRE->drawLayers(settings, layers, mBuffer, true, base::unique_fd(fenceOne->dup()));
2318 ASSERT_TRUE(futureTwo.valid());
2319 auto resultTwo = futureTwo.get();
2320 ASSERT_TRUE(resultTwo.ok());
2321 auto fenceTwo = resultTwo.value();
2322 fenceTwo->waitForever(LOG_TAG);
Derek Sollenbergerec411212021-08-25 10:54:47 -04002323
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002324 // Only cleanup the first time.
Ian Elliott1f0911e2022-09-09 16:31:47 -06002325 if (mRE->canSkipPostRenderCleanup()) {
2326 // Skia's Vk backend may keep the texture alive beyond drawLayersInternal, so
2327 // it never gets added to the cleanup list. In those cases, we can skip.
2328 EXPECT_TRUE(GetParam()->type() == renderengine::RenderEngine::RenderEngineType::SKIA_VK);
2329 } else {
2330 mRE->cleanupPostRender();
2331 EXPECT_TRUE(mRE->canSkipPostRenderCleanup());
2332 }
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002333}
2334
Ana Krulecf9a15d92020-12-11 08:35:00 -08002335TEST_P(RenderEngineTest, testRoundedCornersCrop) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002336 if (!GetParam()->typeSupported()) {
2337 GTEST_SKIP();
2338 }
Alec Mouric0aae732021-01-12 13:32:18 -08002339 initializeRenderEngine();
Ana Krulecf9a15d92020-12-11 08:35:00 -08002340
2341 renderengine::DisplaySettings settings;
2342 settings.physicalDisplay = fullscreenRect();
2343 settings.clip = fullscreenRect();
2344 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2345
Sally Qi59a9f502021-10-12 18:53:23 +00002346 std::vector<renderengine::LayerSettings> layers;
Ana Krulecf9a15d92020-12-11 08:35:00 -08002347
2348 renderengine::LayerSettings redLayer;
2349 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2350 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002351 redLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
2352
Ana Krulecf9a15d92020-12-11 08:35:00 -08002353 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2354 // Red background.
2355 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2356 redLayer.alpha = 1.0f;
2357
Sally Qi59a9f502021-10-12 18:53:23 +00002358 layers.push_back(redLayer);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002359
2360 // Green layer with 1/3 size.
2361 renderengine::LayerSettings greenLayer;
2362 greenLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2363 greenLayer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002364 greenLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
Ana Krulecf9a15d92020-12-11 08:35:00 -08002365 // Bottom right corner is not going to be rounded.
2366 greenLayer.geometry.roundedCornersCrop =
2367 Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3, DEFAULT_DISPLAY_HEIGHT,
2368 DEFAULT_DISPLAY_HEIGHT)
2369 .toFloatRect();
2370 greenLayer.source.solidColor = half3(0.0f, 1.0f, 0.0f);
2371 greenLayer.alpha = 1.0f;
2372
Sally Qi59a9f502021-10-12 18:53:23 +00002373 layers.push_back(greenLayer);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002374
Alec Mouric0aae732021-01-12 13:32:18 -08002375 invokeDraw(settings, layers);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002376
2377 // Corners should be ignored...
2378 // Screen size: width is 128, height is 256.
2379 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 0);
2380 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, 0, DEFAULT_DISPLAY_WIDTH, 1), 0, 0, 0, 0);
2381 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT - 1, 1, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
2382 // Bottom right corner is kept out of the clipping, and it's green.
2383 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1,
2384 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
2385 0, 255, 0, 255);
2386}
2387
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002388TEST_P(RenderEngineTest, testRoundedCornersParentCrop) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002389 if (!GetParam()->typeSupported()) {
2390 GTEST_SKIP();
2391 }
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002392 initializeRenderEngine();
2393
2394 renderengine::DisplaySettings settings;
2395 settings.physicalDisplay = fullscreenRect();
2396 settings.clip = fullscreenRect();
2397 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2398
Sally Qi59a9f502021-10-12 18:53:23 +00002399 std::vector<renderengine::LayerSettings> layers;
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002400
2401 renderengine::LayerSettings redLayer;
2402 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2403 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002404 redLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002405 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2406 // Red background.
2407 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2408 redLayer.alpha = 1.0f;
2409
Sally Qi59a9f502021-10-12 18:53:23 +00002410 layers.push_back(redLayer);
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002411
2412 // Green layer with 1/2 size with parent crop rect.
2413 renderengine::LayerSettings greenLayer = redLayer;
2414 greenLayer.geometry.boundaries =
2415 FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT / 2);
2416 greenLayer.source.solidColor = half3(0.0f, 1.0f, 0.0f);
2417
Sally Qi59a9f502021-10-12 18:53:23 +00002418 layers.push_back(greenLayer);
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002419
2420 invokeDraw(settings, layers);
2421
2422 // Due to roundedCornersRadius, the corners are untouched.
2423 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2424 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2425 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2426 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2427
2428 // top middle should be green and the bottom middle red
2429 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, 0), 0, 255, 0, 255);
2430 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0, 255);
2431
2432 // the bottom edge of the green layer should not be rounded
2433 expectBufferColor(Point(0, (DEFAULT_DISPLAY_HEIGHT / 2) - 1), 0, 255, 0, 255);
2434}
2435
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002436TEST_P(RenderEngineTest, testRoundedCornersParentCropSmallBounds) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002437 if (!GetParam()->typeSupported()) {
2438 GTEST_SKIP();
2439 }
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002440 initializeRenderEngine();
2441
2442 renderengine::DisplaySettings settings;
2443 settings.physicalDisplay = fullscreenRect();
2444 settings.clip = fullscreenRect();
2445 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2446
Sally Qi59a9f502021-10-12 18:53:23 +00002447 std::vector<renderengine::LayerSettings> layers;
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002448
2449 renderengine::LayerSettings redLayer;
2450 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2451 redLayer.geometry.boundaries = FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, 32);
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002452 redLayer.geometry.roundedCornersRadius = {64.0f, 64.0f};
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002453 redLayer.geometry.roundedCornersCrop = FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, 128);
2454 // Red background.
2455 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2456 redLayer.alpha = 1.0f;
2457
Sally Qi59a9f502021-10-12 18:53:23 +00002458 layers.push_back(redLayer);
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002459 invokeDraw(settings, layers);
2460
2461 // Due to roundedCornersRadius, the top corners are untouched.
2462 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2463 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2464
2465 // ensure that the entire height of the red layer was clipped by the rounded corners crop.
2466 expectBufferColor(Point(0, 31), 0, 0, 0, 0);
2467 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 31), 0, 0, 0, 0);
2468
2469 // the bottom middle should be red
2470 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, 31), 255, 0, 0, 255);
2471}
2472
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002473TEST_P(RenderEngineTest, testRoundedCornersXY) {
2474 if (GetParam()->type() != renderengine::RenderEngine::RenderEngineType::SKIA_GL) {
2475 GTEST_SKIP();
2476 }
2477
2478 initializeRenderEngine();
2479
2480 renderengine::DisplaySettings settings;
2481 settings.physicalDisplay = fullscreenRect();
2482 settings.clip = fullscreenRect();
2483 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2484
2485 std::vector<renderengine::LayerSettings> layers;
2486
2487 renderengine::LayerSettings redLayer;
2488 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2489 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
2490 redLayer.geometry.roundedCornersRadius = {5.0f, 20.0f};
2491 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2492 // Red background.
2493 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2494 redLayer.alpha = 1.0f;
2495
2496 layers.push_back(redLayer);
2497
2498 invokeDraw(settings, layers);
2499
2500 // Due to roundedCornersRadius, the corners are untouched.
2501 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2502 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2503 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2504 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2505
2506 // Y-axis draws a larger radius, check that its untouched as well
2507 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 5), 0, 0, 0, 0);
2508 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 5), 0, 0, 0, 0);
2509 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 5), 0, 0, 0, 0);
2510 expectBufferColor(Point(0, 5), 0, 0, 0, 0);
2511
2512 // middle should be red
2513 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0, 255);
2514}
2515
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002516TEST_P(RenderEngineTest, testClear) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002517 if (!GetParam()->typeSupported()) {
2518 GTEST_SKIP();
2519 }
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002520 initializeRenderEngine();
2521
2522 const auto rect = fullscreenRect();
2523 const renderengine::DisplaySettings display{
2524 .physicalDisplay = rect,
2525 .clip = rect,
2526 };
2527
2528 const renderengine::LayerSettings redLayer{
2529 .geometry.boundaries = rect.toFloatRect(),
2530 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
2531 .alpha = 1.0f,
2532 };
2533
2534 // This mimics prepareClearClientComposition. This layer should overwrite
2535 // the redLayer, so that the buffer is transparent, rather than red.
2536 const renderengine::LayerSettings clearLayer{
2537 .geometry.boundaries = rect.toFloatRect(),
2538 .source.solidColor = half3(0.0f, 0.0f, 0.0f),
2539 .alpha = 0.0f,
2540 .disableBlending = true,
2541 };
2542
Sally Qi59a9f502021-10-12 18:53:23 +00002543 std::vector<renderengine::LayerSettings> layers{redLayer, clearLayer};
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002544 invokeDraw(display, layers);
2545 expectBufferColor(rect, 0, 0, 0, 0);
2546}
2547
2548TEST_P(RenderEngineTest, testDisableBlendingBuffer) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002549 if (!GetParam()->typeSupported()) {
2550 GTEST_SKIP();
2551 }
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002552 initializeRenderEngine();
2553
2554 const auto rect = Rect(0, 0, 1, 1);
2555 const renderengine::DisplaySettings display{
2556 .physicalDisplay = rect,
2557 .clip = rect,
2558 };
2559
2560 const renderengine::LayerSettings redLayer{
2561 .geometry.boundaries = rect.toFloatRect(),
2562 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
2563 .alpha = 1.0f,
2564 };
2565
2566 // The next layer will overwrite redLayer with a GraphicBuffer that is green
2567 // applied with a translucent alpha.
Alec Mouria90a5702021-04-16 16:36:21 +00002568 const auto buf = allocateSourceBuffer(1, 1);
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002569 {
2570 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00002571 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2572 reinterpret_cast<void**>(&pixels));
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002573 pixels[0] = 0;
2574 pixels[1] = 255;
2575 pixels[2] = 0;
2576 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00002577 buf->getBuffer()->unlock();
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002578 }
2579
2580 const renderengine::LayerSettings greenLayer{
2581 .geometry.boundaries = rect.toFloatRect(),
2582 .source =
2583 renderengine::PixelSource{
2584 .buffer =
2585 renderengine::Buffer{
2586 .buffer = buf,
2587 .usePremultipliedAlpha = true,
2588 },
2589 },
2590 .alpha = 0.5f,
2591 .disableBlending = true,
2592 };
2593
Sally Qi59a9f502021-10-12 18:53:23 +00002594 std::vector<renderengine::LayerSettings> layers{redLayer, greenLayer};
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002595 invokeDraw(display, layers);
2596 expectBufferColor(rect, 0, 128, 0, 128);
2597}
2598
Tianhao Yao67dd7122022-02-22 17:48:33 +00002599TEST_P(RenderEngineTest, testBorder) {
2600 if (GetParam()->type() != renderengine::RenderEngine::RenderEngineType::SKIA_GL) {
2601 GTEST_SKIP();
2602 }
2603
2604 if (!GetParam()->useColorManagement()) {
2605 GTEST_SKIP();
2606 }
2607
2608 initializeRenderEngine();
2609
2610 const ui::Dataspace dataspace = ui::Dataspace::V0_SRGB;
2611
2612 const auto displayRect = Rect(1080, 2280);
2613 renderengine::DisplaySettings display{
2614 .physicalDisplay = displayRect,
2615 .clip = displayRect,
2616 .outputDataspace = dataspace,
2617 };
2618 display.borderInfoList.clear();
2619 renderengine::BorderRenderInfo info;
2620 info.combinedRegion = Region(Rect(99, 99, 199, 199));
Tianhao Yao10cea3c2022-03-30 01:37:22 +00002621 info.width = 20.0f;
2622 info.color = half4{1.0f, 128.0f / 255.0f, 0.0f, 1.0f};
Tianhao Yao67dd7122022-02-22 17:48:33 +00002623 display.borderInfoList.emplace_back(info);
2624
2625 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2626 const renderengine::LayerSettings greenLayer{
2627 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2628 .source =
2629 renderengine::PixelSource{
2630 .buffer =
2631 renderengine::Buffer{
2632 .buffer = greenBuffer,
2633 .usePremultipliedAlpha = true,
2634 },
2635 },
2636 .alpha = 1.0f,
2637 .sourceDataspace = dataspace,
2638 .whitePointNits = 200.f,
2639 };
2640
2641 std::vector<renderengine::LayerSettings> layers;
2642 layers.emplace_back(greenLayer);
2643 invokeDraw(display, layers);
2644
2645 expectBufferColor(Rect(99, 99, 101, 101), 255, 128, 0, 255, 1);
2646}
2647
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002648TEST_P(RenderEngineTest, testDimming) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002649 if (!GetParam()->typeSupported()) {
2650 GTEST_SKIP();
2651 }
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002652 initializeRenderEngine();
2653
Alec Mouri85065692022-03-18 00:58:26 +00002654 const ui::Dataspace dataspace = ui::Dataspace::V0_SRGB_LINEAR;
2655
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002656 const auto displayRect = Rect(3, 1);
2657 const renderengine::DisplaySettings display{
2658 .physicalDisplay = displayRect,
2659 .clip = displayRect,
Alec Mouri85065692022-03-18 00:58:26 +00002660 .outputDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002661 .targetLuminanceNits = 1000.f,
2662 };
2663
2664 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2665 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2666 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2667
2668 const renderengine::LayerSettings greenLayer{
2669 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2670 .source =
2671 renderengine::PixelSource{
2672 .buffer =
2673 renderengine::Buffer{
2674 .buffer = greenBuffer,
2675 .usePremultipliedAlpha = true,
2676 },
2677 },
2678 .alpha = 1.0f,
Alec Mouri85065692022-03-18 00:58:26 +00002679 .sourceDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002680 .whitePointNits = 200.f,
2681 };
2682
2683 const renderengine::LayerSettings blueLayer{
2684 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2685 .source =
2686 renderengine::PixelSource{
2687 .buffer =
2688 renderengine::Buffer{
2689 .buffer = blueBuffer,
2690 .usePremultipliedAlpha = true,
2691 },
2692 },
2693 .alpha = 1.0f,
Alec Mouri85065692022-03-18 00:58:26 +00002694 .sourceDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002695 .whitePointNits = 1000.f / 51.f,
2696 };
2697
2698 const renderengine::LayerSettings redLayer{
2699 .geometry.boundaries = FloatRect(2.f, 0.f, 3.f, 1.f),
2700 .source =
2701 renderengine::PixelSource{
2702 .buffer =
2703 renderengine::Buffer{
2704 .buffer = redBuffer,
2705 .usePremultipliedAlpha = true,
2706 },
2707 },
2708 .alpha = 1.0f,
Alec Mouri85065692022-03-18 00:58:26 +00002709 .sourceDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002710 // When the white point is not set for a layer, just ignore it and treat it as the same
2711 // as the max layer
2712 .whitePointNits = -1.f,
2713 };
2714
2715 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer, redLayer};
2716 invokeDraw(display, layers);
2717
2718 expectBufferColor(Rect(1, 1), 0, 51, 0, 255, 1);
2719 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 5, 255, 1);
2720 expectBufferColor(Rect(2, 0, 3, 1), 51, 0, 0, 255, 1);
2721}
2722
Alec Mouri85065692022-03-18 00:58:26 +00002723TEST_P(RenderEngineTest, testDimming_inGammaSpace) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002724 if (!GetParam()->typeSupported()) {
2725 GTEST_SKIP();
2726 }
Alec Mouri85065692022-03-18 00:58:26 +00002727 initializeRenderEngine();
2728
2729 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2730 ui::Dataspace::TRANSFER_GAMMA2_2 |
2731 ui::Dataspace::RANGE_FULL);
2732
2733 const auto displayRect = Rect(3, 1);
2734 const renderengine::DisplaySettings display{
2735 .physicalDisplay = displayRect,
2736 .clip = displayRect,
2737 .outputDataspace = dataspace,
2738 .targetLuminanceNits = 1000.f,
2739 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2740 };
2741
2742 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2743 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2744 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2745
2746 const renderengine::LayerSettings greenLayer{
2747 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2748 .source =
2749 renderengine::PixelSource{
2750 .buffer =
2751 renderengine::Buffer{
2752 .buffer = greenBuffer,
2753 .usePremultipliedAlpha = true,
2754 },
2755 },
2756 .alpha = 1.0f,
2757 .sourceDataspace = dataspace,
2758 .whitePointNits = 200.f,
2759 };
2760
2761 const renderengine::LayerSettings blueLayer{
2762 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2763 .source =
2764 renderengine::PixelSource{
2765 .buffer =
2766 renderengine::Buffer{
2767 .buffer = blueBuffer,
2768 .usePremultipliedAlpha = true,
2769 },
2770 },
2771 .alpha = 1.0f,
2772 .sourceDataspace = dataspace,
2773 .whitePointNits = 1000.f / 51.f,
2774 };
2775
2776 const renderengine::LayerSettings redLayer{
2777 .geometry.boundaries = FloatRect(2.f, 0.f, 3.f, 1.f),
2778 .source =
2779 renderengine::PixelSource{
2780 .buffer =
2781 renderengine::Buffer{
2782 .buffer = redBuffer,
2783 .usePremultipliedAlpha = true,
2784 },
2785 },
2786 .alpha = 1.0f,
2787 .sourceDataspace = dataspace,
2788 // When the white point is not set for a layer, just ignore it and treat it as the same
2789 // as the max layer
2790 .whitePointNits = -1.f,
2791 };
2792
2793 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer, redLayer};
2794 invokeDraw(display, layers);
2795
2796 expectBufferColor(Rect(1, 1), 0, 122, 0, 255, 1);
2797 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 42, 255, 1);
2798 expectBufferColor(Rect(2, 0, 3, 1), 122, 0, 0, 255, 1);
2799}
2800
Alec Mouri9bcd1d12022-04-21 22:16:56 +00002801TEST_P(RenderEngineTest, testDimming_inGammaSpace_withDisplayColorTransform) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002802 if (!GetParam()->typeSupported()) {
2803 GTEST_SKIP();
2804 }
Alec Mouri9bcd1d12022-04-21 22:16:56 +00002805 initializeRenderEngine();
2806
2807 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2808 ui::Dataspace::TRANSFER_GAMMA2_2 |
2809 ui::Dataspace::RANGE_FULL);
2810
2811 const auto displayRect = Rect(3, 1);
2812 const renderengine::DisplaySettings display{
2813 .physicalDisplay = displayRect,
2814 .clip = displayRect,
2815 .outputDataspace = dataspace,
2816 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
2817 .targetLuminanceNits = 1000.f,
2818 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2819 };
2820
2821 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2822 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2823 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2824
2825 const renderengine::LayerSettings greenLayer{
2826 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2827 .source =
2828 renderengine::PixelSource{
2829 .buffer =
2830 renderengine::Buffer{
2831 .buffer = greenBuffer,
2832 .usePremultipliedAlpha = true,
2833 },
2834 },
2835 .alpha = 1.0f,
2836 .sourceDataspace = dataspace,
2837 .whitePointNits = 200.f,
2838 };
2839
2840 const renderengine::LayerSettings redLayer{
2841 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2842 .source =
2843 renderengine::PixelSource{
2844 .buffer =
2845 renderengine::Buffer{
2846 .buffer = redBuffer,
2847 .usePremultipliedAlpha = true,
2848 },
2849 },
2850 .alpha = 1.0f,
2851 .sourceDataspace = dataspace,
2852 // When the white point is not set for a layer, just ignore it and treat it as the same
2853 // as the max layer
2854 .whitePointNits = -1.f,
2855 };
2856
2857 std::vector<renderengine::LayerSettings> layers{greenLayer, redLayer};
2858 invokeDraw(display, layers);
2859
2860 expectBufferColor(Rect(1, 1), 0, 0, 0, 255, 1);
2861 expectBufferColor(Rect(1, 0, 2, 1), 0, 122, 0, 255, 1);
2862}
2863
2864TEST_P(RenderEngineTest, testDimming_inGammaSpace_withDisplayColorTransform_deviceHandles) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002865 if (!GetParam()->typeSupported()) {
2866 GTEST_SKIP();
2867 }
Alec Mouri9bcd1d12022-04-21 22:16:56 +00002868 initializeRenderEngine();
2869
2870 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2871 ui::Dataspace::TRANSFER_GAMMA2_2 |
2872 ui::Dataspace::RANGE_FULL);
2873
2874 const auto displayRect = Rect(3, 1);
2875 const renderengine::DisplaySettings display{
2876 .physicalDisplay = displayRect,
2877 .clip = displayRect,
2878 .outputDataspace = dataspace,
2879 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
2880 .deviceHandlesColorTransform = true,
2881 .targetLuminanceNits = 1000.f,
2882 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2883 };
2884
2885 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2886 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2887 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2888
2889 const renderengine::LayerSettings greenLayer{
2890 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2891 .source =
2892 renderengine::PixelSource{
2893 .buffer =
2894 renderengine::Buffer{
2895 .buffer = greenBuffer,
2896 .usePremultipliedAlpha = true,
2897 },
2898 },
2899 .alpha = 1.0f,
2900 .sourceDataspace = dataspace,
2901 .whitePointNits = 200.f,
2902 };
2903
2904 const renderengine::LayerSettings redLayer{
2905 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2906 .source =
2907 renderengine::PixelSource{
2908 .buffer =
2909 renderengine::Buffer{
2910 .buffer = redBuffer,
2911 .usePremultipliedAlpha = true,
2912 },
2913 },
2914 .alpha = 1.0f,
2915 .sourceDataspace = dataspace,
2916 // When the white point is not set for a layer, just ignore it and treat it as the same
2917 // as the max layer
2918 .whitePointNits = -1.f,
2919 };
2920
2921 std::vector<renderengine::LayerSettings> layers{greenLayer, redLayer};
2922 invokeDraw(display, layers);
2923
2924 expectBufferColor(Rect(1, 1), 0, 122, 0, 255, 1);
2925 expectBufferColor(Rect(1, 0, 2, 1), 122, 0, 0, 255, 1);
2926}
2927
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002928TEST_P(RenderEngineTest, testDimming_withoutTargetLuminance) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002929 if (!GetParam()->typeSupported()) {
2930 GTEST_SKIP();
2931 }
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002932 initializeRenderEngine();
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002933
2934 const auto displayRect = Rect(2, 1);
2935 const renderengine::DisplaySettings display{
2936 .physicalDisplay = displayRect,
2937 .clip = displayRect,
2938 .outputDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2939 .targetLuminanceNits = -1.f,
2940 };
2941
2942 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2943 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2944
2945 const renderengine::LayerSettings greenLayer{
2946 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2947 .source =
2948 renderengine::PixelSource{
2949 .buffer =
2950 renderengine::Buffer{
2951 .buffer = greenBuffer,
2952 .usePremultipliedAlpha = true,
2953 },
2954 },
2955 .alpha = 1.0f,
2956 .sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2957 .whitePointNits = 200.f,
2958 };
2959
2960 const renderengine::LayerSettings blueLayer{
2961 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2962 .source =
2963 renderengine::PixelSource{
2964 .buffer =
2965 renderengine::Buffer{
2966 .buffer = blueBuffer,
2967 .usePremultipliedAlpha = true,
2968 },
2969 },
2970 .alpha = 1.0f,
2971 .sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2972 .whitePointNits = 1000.f,
2973 };
2974
2975 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer};
2976 invokeDraw(display, layers);
2977
2978 expectBufferColor(Rect(1, 1), 0, 51, 0, 255, 1);
2979 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 255, 255);
2980}
2981
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002982TEST_P(RenderEngineTest, test_isOpaque) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002983 if (!GetParam()->typeSupported()) {
2984 GTEST_SKIP();
2985 }
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002986 initializeRenderEngine();
2987
2988 const auto rect = Rect(0, 0, 1, 1);
2989 const renderengine::DisplaySettings display{
2990 .physicalDisplay = rect,
2991 .clip = rect,
2992 .outputDataspace = ui::Dataspace::DISPLAY_P3,
2993 };
2994
2995 // Create an unpremul buffer that is green with no alpha. Using isOpaque
2996 // should make the green show.
2997 const auto buf = allocateSourceBuffer(1, 1);
2998 {
2999 uint8_t* pixels;
3000 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
3001 reinterpret_cast<void**>(&pixels));
3002 pixels[0] = 0;
3003 pixels[1] = 255;
3004 pixels[2] = 0;
3005 pixels[3] = 0;
3006 buf->getBuffer()->unlock();
3007 }
3008
3009 const renderengine::LayerSettings greenLayer{
3010 .geometry.boundaries = rect.toFloatRect(),
3011 .source =
3012 renderengine::PixelSource{
3013 .buffer =
3014 renderengine::Buffer{
3015 .buffer = buf,
3016 // Although the pixels are not
3017 // premultiplied in practice, this
3018 // matches the input we see.
3019 .usePremultipliedAlpha = true,
3020 .isOpaque = true,
3021 },
3022 },
3023 .alpha = 1.0f,
3024 };
3025
Sally Qi59a9f502021-10-12 18:53:23 +00003026 std::vector<renderengine::LayerSettings> layers{greenLayer};
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04003027 invokeDraw(display, layers);
3028
3029 if (GetParam()->useColorManagement()) {
3030 expectBufferColor(rect, 117, 251, 76, 255);
3031 } else {
3032 expectBufferColor(rect, 0, 255, 0, 255);
3033 }
3034}
Alec Mouri4049b532021-10-15 20:59:33 -07003035
Alec Mouri4049b532021-10-15 20:59:33 -07003036TEST_P(RenderEngineTest, test_tonemapPQMatches) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003037 if (!GetParam()->typeSupported() || !GetParam()->useColorManagement()) {
Alec Mouri5a493722022-01-26 16:43:02 -08003038 GTEST_SKIP();
Alec Mouri4049b532021-10-15 20:59:33 -07003039 }
3040
Alec Mouri4049b532021-10-15 20:59:33 -07003041 initializeRenderEngine();
3042
Alec Mouri5a493722022-01-26 16:43:02 -08003043 tonemap(
3044 static_cast<ui::Dataspace>(HAL_DATASPACE_STANDARD_BT2020 |
3045 HAL_DATASPACE_TRANSFER_ST2084 | HAL_DATASPACE_RANGE_FULL),
3046 [](vec3 color) { return EOTF_PQ(color); },
3047 [](vec3 color, float) {
3048 static constexpr float kMaxPQLuminance = 10000.f;
3049 return color * kMaxPQLuminance;
3050 });
3051}
Alec Mouri4049b532021-10-15 20:59:33 -07003052
Alec Mouri5a493722022-01-26 16:43:02 -08003053TEST_P(RenderEngineTest, test_tonemapHLGMatches) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003054 if (!GetParam()->typeSupported() || !GetParam()->useColorManagement()) {
Alec Mouri5a493722022-01-26 16:43:02 -08003055 GTEST_SKIP();
Alec Mouri4049b532021-10-15 20:59:33 -07003056 }
3057
Alec Mouri5a493722022-01-26 16:43:02 -08003058 initializeRenderEngine();
Alec Mouri4049b532021-10-15 20:59:33 -07003059
Alec Mouri5a493722022-01-26 16:43:02 -08003060 tonemap(
3061 static_cast<ui::Dataspace>(HAL_DATASPACE_STANDARD_BT2020 | HAL_DATASPACE_TRANSFER_HLG |
3062 HAL_DATASPACE_RANGE_FULL),
3063 [](vec3 color) { return EOTF_HLG(color); },
3064 [](vec3 color, float currentLuminaceNits) {
3065 static constexpr float kMaxHLGLuminance = 1000.f;
Alec Mouri7a577452022-03-04 23:41:38 +00003066 return color * kMaxHLGLuminance;
Alec Mouri5a493722022-01-26 16:43:02 -08003067 });
Alec Mouri4049b532021-10-15 20:59:33 -07003068}
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -05003069
3070TEST_P(RenderEngineTest, r8_behaves_as_mask) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003071 if (!GetParam()->typeSupported()) {
3072 GTEST_SKIP();
3073 }
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -05003074 initializeRenderEngine();
3075
3076 const auto r8Buffer = allocateR8Buffer(2, 1);
3077 if (!r8Buffer) {
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003078 GTEST_SKIP() << "Test is only necessary on devices that support r8";
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -05003079 return;
3080 }
3081 {
3082 uint8_t* pixels;
3083 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
3084 reinterpret_cast<void**>(&pixels));
3085 // This will be drawn on top of a green buffer. We'll verify that 255
3086 // results in keeping the original green and 0 results in black.
3087 pixels[0] = 0;
3088 pixels[1] = 255;
3089 r8Buffer->getBuffer()->unlock();
3090 }
3091
3092 const auto rect = Rect(0, 0, 2, 1);
3093 const renderengine::DisplaySettings display{
3094 .physicalDisplay = rect,
3095 .clip = rect,
3096 .outputDataspace = ui::Dataspace::SRGB,
3097 };
3098
3099 const auto greenBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(0, 255, 0, 255));
3100 const renderengine::LayerSettings greenLayer{
3101 .geometry.boundaries = rect.toFloatRect(),
3102 .source =
3103 renderengine::PixelSource{
3104 .buffer =
3105 renderengine::Buffer{
3106 .buffer = greenBuffer,
3107 },
3108 },
3109 .alpha = 1.0f,
3110 };
3111 const renderengine::LayerSettings r8Layer{
3112 .geometry.boundaries = rect.toFloatRect(),
3113 .source =
3114 renderengine::PixelSource{
3115 .buffer =
3116 renderengine::Buffer{
3117 .buffer = r8Buffer,
3118 },
3119 },
3120 .alpha = 1.0f,
3121 };
3122
3123 std::vector<renderengine::LayerSettings> layers{greenLayer, r8Layer};
3124 invokeDraw(display, layers);
3125
3126 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 255);
3127 expectBufferColor(Rect(1, 0, 2, 1), 0, 255, 0, 255);
3128}
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003129
3130TEST_P(RenderEngineTest, r8_respects_color_transform) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003131 if (!GetParam()->typeSupported()) {
3132 GTEST_SKIP();
3133 }
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003134 initializeRenderEngine();
3135
3136 const auto r8Buffer = allocateR8Buffer(2, 1);
3137 if (!r8Buffer) {
3138 GTEST_SKIP() << "Test is only necessary on devices that support r8";
3139 return;
3140 }
3141 {
3142 uint8_t* pixels;
3143 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
3144 reinterpret_cast<void**>(&pixels));
3145 pixels[0] = 0;
3146 pixels[1] = 255;
3147 r8Buffer->getBuffer()->unlock();
3148 }
3149
3150 const auto rect = Rect(0, 0, 2, 1);
3151 const renderengine::DisplaySettings display{
3152 .physicalDisplay = rect,
3153 .clip = rect,
3154 .outputDataspace = ui::Dataspace::SRGB,
3155 // Verify that the R8 layer respects the color transform when
3156 // deviceHandlesColorTransform is false. This transform converts
3157 // pure red to pure green. That will occur when the R8 buffer is
3158 // 255. When the R8 buffer is 0, it will still change to black, as
3159 // with r8_behaves_as_mask.
Alec Mouri9bcd1d12022-04-21 22:16:56 +00003160 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003161 .deviceHandlesColorTransform = false,
3162 };
3163
3164 const auto redBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(255, 0, 0, 255));
3165 const renderengine::LayerSettings redLayer{
3166 .geometry.boundaries = rect.toFloatRect(),
3167 .source =
3168 renderengine::PixelSource{
3169 .buffer =
3170 renderengine::Buffer{
3171 .buffer = redBuffer,
3172 },
3173 },
3174 .alpha = 1.0f,
3175 };
3176 const renderengine::LayerSettings r8Layer{
3177 .geometry.boundaries = rect.toFloatRect(),
3178 .source =
3179 renderengine::PixelSource{
3180 .buffer =
3181 renderengine::Buffer{
3182 .buffer = r8Buffer,
3183 },
3184 },
3185 .alpha = 1.0f,
3186 };
3187
3188 std::vector<renderengine::LayerSettings> layers{redLayer, r8Layer};
3189 invokeDraw(display, layers);
3190
3191 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 255);
3192 expectBufferColor(Rect(1, 0, 2, 1), 0, 255, 0, 255);
3193}
3194
3195TEST_P(RenderEngineTest, r8_respects_color_transform_when_device_handles) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003196 if (!GetParam()->typeSupported()) {
3197 GTEST_SKIP();
3198 }
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003199 initializeRenderEngine();
3200
3201 const auto r8Buffer = allocateR8Buffer(2, 1);
3202 if (!r8Buffer) {
3203 GTEST_SKIP() << "Test is only necessary on devices that support r8";
3204 return;
3205 }
3206 {
3207 uint8_t* pixels;
3208 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
3209 reinterpret_cast<void**>(&pixels));
3210 pixels[0] = 0;
3211 pixels[1] = 255;
3212 r8Buffer->getBuffer()->unlock();
3213 }
3214
3215 const auto rect = Rect(0, 0, 2, 1);
3216 const renderengine::DisplaySettings display{
3217 .physicalDisplay = rect,
3218 .clip = rect,
3219 .outputDataspace = ui::Dataspace::SRGB,
3220 // If deviceHandlesColorTransform is true, pixels where the A8
3221 // buffer is opaque are unaffected. If the colorTransform is
3222 // invertible, pixels where the A8 buffer are transparent have the
3223 // inverse applied to them so that the DPU will convert them back to
3224 // black. Test with an arbitrary, invertible matrix.
3225 .colorTransform = mat4(1, 0, 0, 2,
3226 3, 1, 2, 5,
3227 0, 5, 3, 0,
3228 0, 1, 0, 2),
3229 .deviceHandlesColorTransform = true,
3230 };
3231
3232 const auto redBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(255, 0, 0, 255));
3233 const renderengine::LayerSettings redLayer{
3234 .geometry.boundaries = rect.toFloatRect(),
3235 .source =
3236 renderengine::PixelSource{
3237 .buffer =
3238 renderengine::Buffer{
3239 .buffer = redBuffer,
3240 },
3241 },
3242 .alpha = 1.0f,
3243 };
3244 const renderengine::LayerSettings r8Layer{
3245 .geometry.boundaries = rect.toFloatRect(),
3246 .source =
3247 renderengine::PixelSource{
3248 .buffer =
3249 renderengine::Buffer{
3250 .buffer = r8Buffer,
3251 },
3252 },
3253 .alpha = 1.0f,
3254 };
3255
3256 std::vector<renderengine::LayerSettings> layers{redLayer, r8Layer};
3257 invokeDraw(display, layers);
3258
3259 expectBufferColor(Rect(1, 0, 2, 1), 255, 0, 0, 255); // Still red.
3260 expectBufferColor(Rect(0, 0, 1, 1), 0, 70, 0, 255);
3261}
Leon Scroggins III45be9182022-04-27 10:37:11 -04003262
3263TEST_P(RenderEngineTest, primeShaderCache) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003264 if (!GetParam()->typeSupported()) {
3265 GTEST_SKIP();
3266 }
Leon Scroggins III45be9182022-04-27 10:37:11 -04003267 initializeRenderEngine();
3268
3269 auto fut = mRE->primeCache();
3270 if (fut.valid()) {
3271 fut.wait();
3272 }
3273
3274 const int minimumExpectedShadersCompiled = GetParam()->useColorManagement() ? 60 : 30;
3275 ASSERT_GT(static_cast<skia::SkiaGLRenderEngine*>(mRE.get())->reportShadersCompiled(),
3276 minimumExpectedShadersCompiled);
3277}
Derek Sollenbergerd3f60652021-06-11 15:34:36 -04003278} // namespace renderengine
Alec Mouri6e57f682018-09-29 20:45:08 -07003279} // namespace android
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08003280
3281// TODO(b/129481165): remove the #pragma below and fix conversion issues
Marin Shalamanovbed7fd32020-12-21 20:02:20 +01003282#pragma clang diagnostic pop // ignored "-Wconversion -Wextra"