blob: 1ad0fa6e7056e54bc81934983d12461772f815a9 [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;
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800112};
113
Ian Elliott1f0911e2022-09-09 16:31:47 -0600114class SkiaVkRenderEngineFactory : public RenderEngineFactory {
115public:
116 std::string name() override { return "SkiaVkRenderEngineFactory"; }
117
118 renderengine::RenderEngine::RenderEngineType type() {
119 return renderengine::RenderEngine::RenderEngineType::SKIA_VK;
120 }
121
122 std::unique_ptr<renderengine::RenderEngine> createRenderEngine() override {
123 std::unique_ptr<renderengine::RenderEngine> re = createSkiaVkRenderEngine();
124 return re;
125 }
126
127 std::unique_ptr<renderengine::skia::SkiaVkRenderEngine> createSkiaVkRenderEngine() {
128 renderengine::RenderEngineCreationArgs reCreationArgs =
129 renderengine::RenderEngineCreationArgs::Builder()
130 .setPixelFormat(static_cast<int>(ui::PixelFormat::RGBA_8888))
131 .setImageCacheSize(1)
Ian Elliott1f0911e2022-09-09 16:31:47 -0600132 .setEnableProtectedContext(false)
133 .setPrecacheToneMapperShaderOnly(false)
134 .setSupportsBackgroundBlur(true)
135 .setContextPriority(renderengine::RenderEngine::ContextPriority::MEDIUM)
136 .setRenderEngineType(type())
Ian Elliott1f0911e2022-09-09 16:31:47 -0600137 .build();
138 return renderengine::skia::SkiaVkRenderEngine::create(reCreationArgs);
139 }
140
141 bool typeSupported() override {
142 return skia::SkiaVkRenderEngine::canSupportSkiaVkRenderEngine();
143 }
Ian Elliott1f0911e2022-09-09 16:31:47 -0600144 void skip() { GTEST_SKIP(); }
145};
146
Alec Mouri0eab3e82020-12-08 18:10:27 -0800147class SkiaGLESRenderEngineFactory : public RenderEngineFactory {
148public:
Alec Mouric0aae732021-01-12 13:32:18 -0800149 std::string name() override { return "SkiaGLRenderEngineFactory"; }
Alec Mouri0eab3e82020-12-08 18:10:27 -0800150
Alec Mouric0aae732021-01-12 13:32:18 -0800151 renderengine::RenderEngine::RenderEngineType type() {
152 return renderengine::RenderEngine::RenderEngineType::SKIA_GL;
153 }
154
155 std::unique_ptr<renderengine::RenderEngine> createRenderEngine() override {
Alec Mouri0eab3e82020-12-08 18:10:27 -0800156 renderengine::RenderEngineCreationArgs reCreationArgs =
157 renderengine::RenderEngineCreationArgs::Builder()
158 .setPixelFormat(static_cast<int>(ui::PixelFormat::RGBA_8888))
159 .setImageCacheSize(1)
160 .setEnableProtectedContext(false)
161 .setPrecacheToneMapperShaderOnly(false)
162 .setSupportsBackgroundBlur(true)
163 .setContextPriority(renderengine::RenderEngine::ContextPriority::MEDIUM)
Alec Mouric0aae732021-01-12 13:32:18 -0800164 .setRenderEngineType(type())
Alec Mouri0eab3e82020-12-08 18:10:27 -0800165 .build();
Alec Mouric0aae732021-01-12 13:32:18 -0800166 return renderengine::skia::SkiaGLRenderEngine::create(reCreationArgs);
Alec Mouri0eab3e82020-12-08 18:10:27 -0800167 }
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -0400168
Ian Elliott1f0911e2022-09-09 16:31:47 -0600169 bool typeSupported() override { return true; }
Alec Mouri0eab3e82020-12-08 18:10:27 -0800170};
171
172class SkiaGLESCMRenderEngineFactory : public RenderEngineFactory {
173public:
Alec Mouric0aae732021-01-12 13:32:18 -0800174 std::string name() override { return "SkiaGLCMRenderEngineFactory"; }
Alec Mouri0eab3e82020-12-08 18:10:27 -0800175
Alec Mouric0aae732021-01-12 13:32:18 -0800176 renderengine::RenderEngine::RenderEngineType type() {
177 return renderengine::RenderEngine::RenderEngineType::SKIA_GL;
178 }
179
180 std::unique_ptr<renderengine::RenderEngine> createRenderEngine() override {
Alec Mouri0eab3e82020-12-08 18:10:27 -0800181 renderengine::RenderEngineCreationArgs reCreationArgs =
182 renderengine::RenderEngineCreationArgs::Builder()
183 .setPixelFormat(static_cast<int>(ui::PixelFormat::RGBA_8888))
184 .setImageCacheSize(1)
185 .setEnableProtectedContext(false)
186 .setPrecacheToneMapperShaderOnly(false)
187 .setSupportsBackgroundBlur(true)
188 .setContextPriority(renderengine::RenderEngine::ContextPriority::MEDIUM)
Alec Mouric0aae732021-01-12 13:32:18 -0800189 .setRenderEngineType(type())
Alec Mouri0eab3e82020-12-08 18:10:27 -0800190 .build();
Alec Mouric0aae732021-01-12 13:32:18 -0800191 return renderengine::skia::SkiaGLRenderEngine::create(reCreationArgs);
Alec Mouri0eab3e82020-12-08 18:10:27 -0800192 }
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -0400193
Ian Elliott1f0911e2022-09-09 16:31:47 -0600194 bool typeSupported() override { return true; }
Alec Mouri0eab3e82020-12-08 18:10:27 -0800195};
196
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800197class RenderEngineTest : public ::testing::TestWithParam<std::shared_ptr<RenderEngineFactory>> {
198public:
Alec Mouria90a5702021-04-16 16:36:21 +0000199 std::shared_ptr<renderengine::ExternalTexture> allocateDefaultBuffer() {
200 return std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800201 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -0700202 ExternalTexture>(sp<GraphicBuffer>::
203 make(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT,
204 HAL_PIXEL_FORMAT_RGBA_8888, 1,
205 GRALLOC_USAGE_SW_READ_OFTEN |
206 GRALLOC_USAGE_SW_WRITE_OFTEN |
207 GRALLOC_USAGE_HW_RENDER |
208 GRALLOC_USAGE_HW_TEXTURE,
209 "output"),
Alec Mouria90a5702021-04-16 16:36:21 +0000210 *mRE,
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800211 renderengine::impl::ExternalTexture::Usage::READABLE |
212 renderengine::impl::ExternalTexture::Usage::
213 WRITEABLE);
Alec Mouri6e57f682018-09-29 20:45:08 -0700214 }
215
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800216 // Allocates a 1x1 buffer to fill with a solid color
Alec Mouria90a5702021-04-16 16:36:21 +0000217 std::shared_ptr<renderengine::ExternalTexture> allocateSourceBuffer(uint32_t width,
218 uint32_t height) {
219 return std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800220 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -0700221 ExternalTexture>(sp<GraphicBuffer>::
222 make(width, height, HAL_PIXEL_FORMAT_RGBA_8888, 1,
223 GRALLOC_USAGE_SW_READ_OFTEN |
224 GRALLOC_USAGE_SW_WRITE_OFTEN |
225 GRALLOC_USAGE_HW_TEXTURE,
226 "input"),
Alec Mouria90a5702021-04-16 16:36:21 +0000227 *mRE,
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800228 renderengine::impl::ExternalTexture::Usage::READABLE |
229 renderengine::impl::ExternalTexture::Usage::
230 WRITEABLE);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800231 }
232
Alec Mouricdf6cbc2021-11-01 17:21:15 -0700233 std::shared_ptr<renderengine::ExternalTexture> allocateAndFillSourceBuffer(uint32_t width,
234 uint32_t height,
235 ubyte4 color) {
236 const auto buffer = allocateSourceBuffer(width, height);
237 uint8_t* pixels;
238 buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
239 reinterpret_cast<void**>(&pixels));
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -0500240 for (uint32_t j = 0; j < height; j++) {
241 uint8_t* dst = pixels + (buffer->getBuffer()->getStride() * j * 4);
242 for (uint32_t i = 0; i < width; i++) {
243 dst[0] = color.r;
244 dst[1] = color.g;
245 dst[2] = color.b;
246 dst[3] = color.a;
247 dst += 4;
248 }
249 }
Alec Mouricdf6cbc2021-11-01 17:21:15 -0700250 buffer->getBuffer()->unlock();
251 return buffer;
252 }
253
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -0500254 std::shared_ptr<renderengine::ExternalTexture> allocateR8Buffer(int width, int height) {
Ady Abrahamd11bade2022-08-01 16:18:03 -0700255 const auto kUsageFlags =
256 static_cast<uint64_t>(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
257 GRALLOC_USAGE_HW_TEXTURE);
258 auto buffer =
259 sp<GraphicBuffer>::make(static_cast<uint32_t>(width), static_cast<uint32_t>(height),
260 android::PIXEL_FORMAT_R_8, 1u, kUsageFlags, "r8");
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -0500261 if (buffer->initCheck() != 0) {
262 // Devices are not required to support R8.
263 return nullptr;
264 }
265 return std::make_shared<
266 renderengine::impl::ExternalTexture>(std::move(buffer), *mRE,
267 renderengine::impl::ExternalTexture::Usage::
268 READABLE);
269 }
270
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800271 RenderEngineTest() {
272 const ::testing::TestInfo* const test_info =
273 ::testing::UnitTest::GetInstance()->current_test_info();
274 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800275 }
Alec Mouri1089aed2018-10-25 21:33:57 -0700276
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800277 ~RenderEngineTest() {
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800278 if (WRITE_BUFFER_TO_FILE_ON_FAILURE && ::testing::Test::HasFailure()) {
279 writeBufferToFile("/data/texture_out_");
280 }
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800281 for (uint32_t texName : mTexNames) {
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800282 mRE->deleteTextures(1, &texName);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800283 }
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800284 const ::testing::TestInfo* const test_info =
285 ::testing::UnitTest::GetInstance()->current_test_info();
286 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800287 }
288
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800289 void writeBufferToFile(const char* basename) {
290 std::string filename(basename);
291 filename.append(::testing::UnitTest::GetInstance()->current_test_info()->name());
292 filename.append(".ppm");
293 std::ofstream file(filename.c_str(), std::ios::binary);
294 if (!file.is_open()) {
295 ALOGE("Unable to open file: %s", filename.c_str());
296 ALOGE("You may need to do: \"adb shell setenforce 0\" to enable "
297 "surfaceflinger to write debug images");
298 return;
299 }
300
Alec Mouri1089aed2018-10-25 21:33:57 -0700301 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +0000302 mBuffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
303 reinterpret_cast<void**>(&pixels));
Alec Mouri1089aed2018-10-25 21:33:57 -0700304
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800305 file << "P6\n";
Alec Mouria90a5702021-04-16 16:36:21 +0000306 file << mBuffer->getBuffer()->getWidth() << "\n";
307 file << mBuffer->getBuffer()->getHeight() << "\n";
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800308 file << 255 << "\n";
309
Alec Mouria90a5702021-04-16 16:36:21 +0000310 std::vector<uint8_t> outBuffer(mBuffer->getBuffer()->getWidth() *
311 mBuffer->getBuffer()->getHeight() * 3);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800312 auto outPtr = reinterpret_cast<uint8_t*>(outBuffer.data());
313
Alec Mouria90a5702021-04-16 16:36:21 +0000314 for (int32_t j = 0; j < mBuffer->getBuffer()->getHeight(); j++) {
315 const uint8_t* src = pixels + (mBuffer->getBuffer()->getStride() * j) * 4;
316 for (int32_t i = 0; i < mBuffer->getBuffer()->getWidth(); i++) {
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800317 // Only copy R, G and B components
318 outPtr[0] = src[0];
319 outPtr[1] = src[1];
320 outPtr[2] = src[2];
321 outPtr += 3;
322
323 src += 4;
324 }
325 }
326 file.write(reinterpret_cast<char*>(outBuffer.data()), outBuffer.size());
Alec Mouria90a5702021-04-16 16:36:21 +0000327 mBuffer->getBuffer()->unlock();
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800328 }
329
330 void expectBufferColor(const Region& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
331 size_t c;
332 Rect const* rect = region.getArray(&c);
333 for (size_t i = 0; i < c; i++, rect++) {
334 expectBufferColor(*rect, r, g, b, a);
335 }
336 }
337
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -0400338 void expectBufferColor(const Point& point, uint8_t r, uint8_t g, uint8_t b, uint8_t a,
339 uint8_t tolerance = 0) {
340 expectBufferColor(Rect(point.x, point.y, point.x + 1, point.y + 1), r, g, b, a, tolerance);
341 }
342
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800343 void expectBufferColor(const Rect& rect, uint8_t r, uint8_t g, uint8_t b, uint8_t a,
344 uint8_t tolerance = 0) {
Alec Mouri4049b532021-10-15 20:59:33 -0700345 auto generator = [=](Point) { return ubyte4(r, g, b, a); };
346 expectBufferColor(rect, generator, tolerance);
347 }
348
349 using ColorGenerator = std::function<ubyte4(Point location)>;
350
351 void expectBufferColor(const Rect& rect, ColorGenerator generator, uint8_t tolerance = 0) {
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800352 auto colorCompare = [tolerance](const uint8_t* colorA, const uint8_t* colorB) {
353 auto colorBitCompare = [tolerance](uint8_t a, uint8_t b) {
354 uint8_t tmp = a >= b ? a - b : b - a;
355 return tmp <= tolerance;
356 };
357 return std::equal(colorA, colorA + 4, colorB, colorBitCompare);
Alec Mouri1089aed2018-10-25 21:33:57 -0700358 };
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800359
Alec Mouri4049b532021-10-15 20:59:33 -0700360 expectBufferColor(rect, generator, colorCompare);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800361 }
362
Alec Mouri4049b532021-10-15 20:59:33 -0700363 void expectBufferColor(const Rect& region, ColorGenerator generator,
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800364 std::function<bool(const uint8_t* a, const uint8_t* b)> colorCompare) {
365 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +0000366 mBuffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
367 reinterpret_cast<void**>(&pixels));
Alec Mouri1089aed2018-10-25 21:33:57 -0700368 int32_t maxFails = 10;
369 int32_t fails = 0;
370 for (int32_t j = 0; j < region.getHeight(); j++) {
Alec Mouria90a5702021-04-16 16:36:21 +0000371 const uint8_t* src = pixels +
372 (mBuffer->getBuffer()->getStride() * (region.top + j) + region.left) * 4;
Alec Mouri1089aed2018-10-25 21:33:57 -0700373 for (int32_t i = 0; i < region.getWidth(); i++) {
Alec Mouri4049b532021-10-15 20:59:33 -0700374 const auto location = Point(region.left + i, region.top + j);
375 const ubyte4 colors = generator(location);
376 const uint8_t expected[4] = {colors.r, colors.g, colors.b, colors.a};
377 bool colorMatches = colorCompare(src, expected);
378 EXPECT_TRUE(colorMatches)
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -0400379 << GetParam()->name().c_str() << ": "
Alec Mouri4049b532021-10-15 20:59:33 -0700380 << "pixel @ (" << location.x << ", " << location.y << "): "
381 << "expected (" << static_cast<uint32_t>(colors.r) << ", "
382 << static_cast<uint32_t>(colors.g) << ", "
383 << static_cast<uint32_t>(colors.b) << ", "
384 << static_cast<uint32_t>(colors.a) << "), "
Alec Mouri1089aed2018-10-25 21:33:57 -0700385 << "got (" << static_cast<uint32_t>(src[0]) << ", "
386 << static_cast<uint32_t>(src[1]) << ", " << static_cast<uint32_t>(src[2])
387 << ", " << static_cast<uint32_t>(src[3]) << ")";
388 src += 4;
Alec Mouri4049b532021-10-15 20:59:33 -0700389 if (!colorMatches && ++fails >= maxFails) {
Alec Mouri1089aed2018-10-25 21:33:57 -0700390 break;
391 }
392 }
393 if (fails >= maxFails) {
394 break;
395 }
396 }
Alec Mouria90a5702021-04-16 16:36:21 +0000397 mBuffer->getBuffer()->unlock();
Alec Mouri1089aed2018-10-25 21:33:57 -0700398 }
399
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800400 void expectAlpha(const Rect& rect, uint8_t a) {
Alec Mouri4049b532021-10-15 20:59:33 -0700401 auto generator = [=](Point) { return ubyte4(0, 0, 0, a); };
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800402 auto colorCompare = [](const uint8_t* colorA, const uint8_t* colorB) {
403 return colorA[3] == colorB[3];
404 };
Alec Mouri4049b532021-10-15 20:59:33 -0700405 expectBufferColor(rect, generator, colorCompare);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800406 }
407
408 void expectShadowColor(const renderengine::LayerSettings& castingLayer,
409 const renderengine::ShadowSettings& shadow, const ubyte4& casterColor,
410 const ubyte4& backgroundColor) {
411 const Rect casterRect(castingLayer.geometry.boundaries);
412 Region casterRegion = Region(casterRect);
Vishnu Nair50c0afe2022-07-11 15:04:07 -0700413 const float casterCornerRadius = (castingLayer.geometry.roundedCornersRadius.x +
414 castingLayer.geometry.roundedCornersRadius.y) /
415 2.0;
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800416 if (casterCornerRadius > 0.0f) {
417 // ignore the corners if a corner radius is set
418 Rect cornerRect(casterCornerRadius, casterCornerRadius);
419 casterRegion.subtractSelf(cornerRect.offsetTo(casterRect.left, casterRect.top));
420 casterRegion.subtractSelf(
421 cornerRect.offsetTo(casterRect.right - casterCornerRadius, casterRect.top));
422 casterRegion.subtractSelf(
423 cornerRect.offsetTo(casterRect.left, casterRect.bottom - casterCornerRadius));
424 casterRegion.subtractSelf(cornerRect.offsetTo(casterRect.right - casterCornerRadius,
425 casterRect.bottom - casterCornerRadius));
426 }
427
428 const float shadowInset = shadow.length * -1.0f;
429 const Rect casterWithShadow =
430 Rect(casterRect).inset(shadowInset, shadowInset, shadowInset, shadowInset);
431 const Region shadowRegion = Region(casterWithShadow).subtractSelf(casterRect);
432 const Region backgroundRegion = Region(fullscreenRect()).subtractSelf(casterWithShadow);
433
434 // verify casting layer
435 expectBufferColor(casterRegion, casterColor.r, casterColor.g, casterColor.b, casterColor.a);
436
437 // verify shadows by testing just the alpha since its difficult to validate the shadow color
438 size_t c;
439 Rect const* r = shadowRegion.getArray(&c);
440 for (size_t i = 0; i < c; i++, r++) {
441 expectAlpha(*r, 255);
442 }
443
444 // verify background
445 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
446 backgroundColor.a);
447 }
448
Alec Mouribd17b3b2020-12-17 11:08:30 -0800449 void expectShadowColorWithoutCaster(const FloatRect& casterBounds,
450 const renderengine::ShadowSettings& shadow,
451 const ubyte4& backgroundColor) {
452 const float shadowInset = shadow.length * -1.0f;
453 const Rect casterRect(casterBounds);
454 const Rect shadowRect =
455 Rect(casterRect).inset(shadowInset, shadowInset, shadowInset, shadowInset);
456
457 const Region backgroundRegion =
458 Region(fullscreenRect()).subtractSelf(casterRect).subtractSelf(shadowRect);
459
460 expectAlpha(shadowRect, 255);
461 // (0, 0, 0) fill on the bounds of the layer should be ignored.
462 expectBufferColor(casterRect, 255, 255, 255, 255, 254);
463
464 // verify background
465 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
466 backgroundColor.a);
467 }
468
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800469 static renderengine::ShadowSettings getShadowSettings(const vec2& casterPos, float shadowLength,
470 bool casterIsTranslucent) {
471 renderengine::ShadowSettings shadow;
472 shadow.ambientColor = {0.0f, 0.0f, 0.0f, 0.039f};
473 shadow.spotColor = {0.0f, 0.0f, 0.0f, 0.19f};
474 shadow.lightPos = vec3(casterPos.x, casterPos.y, 0);
475 shadow.lightRadius = 0.0f;
476 shadow.length = shadowLength;
477 shadow.casterIsTranslucent = casterIsTranslucent;
478 return shadow;
479 }
480
Alec Mouri1089aed2018-10-25 21:33:57 -0700481 static Rect fullscreenRect() { return Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT); }
482
483 static Rect offsetRect() {
484 return Rect(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_WIDTH,
485 DEFAULT_DISPLAY_HEIGHT);
486 }
487
488 static Rect offsetRectAtZero() {
489 return Rect(DEFAULT_DISPLAY_WIDTH - DEFAULT_DISPLAY_OFFSET,
490 DEFAULT_DISPLAY_HEIGHT - DEFAULT_DISPLAY_OFFSET);
491 }
492
Sally Qi59a9f502021-10-12 18:53:23 +0000493 void invokeDraw(const renderengine::DisplaySettings& settings,
494 const std::vector<renderengine::LayerSettings>& layers) {
Patrick Williams2e9748f2022-08-09 22:48:18 +0000495 ftl::Future<FenceResult> future =
Sally Qi4cabdd02021-08-05 16:45:57 -0700496 mRE->drawLayers(settings, layers, mBuffer, true, base::unique_fd());
Patrick Williams2e9748f2022-08-09 22:48:18 +0000497 ASSERT_TRUE(future.valid());
Sally Qi59a9f502021-10-12 18:53:23 +0000498
Patrick Williams2e9748f2022-08-09 22:48:18 +0000499 auto result = future.get();
500 ASSERT_TRUE(result.ok());
Alec Mouri1089aed2018-10-25 21:33:57 -0700501
Patrick Williams2e9748f2022-08-09 22:48:18 +0000502 auto fence = result.value();
503 fence->waitForever(LOG_TAG);
Alec Mouri1089aed2018-10-25 21:33:57 -0700504 }
505
Alec Mourid43ccab2019-03-13 12:23:45 -0700506 void drawEmptyLayers() {
Alec Mouri6e57f682018-09-29 20:45:08 -0700507 renderengine::DisplaySettings settings;
Sally Qi59a9f502021-10-12 18:53:23 +0000508 std::vector<renderengine::LayerSettings> layers;
Alec Mouric0aae732021-01-12 13:32:18 -0800509 invokeDraw(settings, layers);
Alec Mouri6e57f682018-09-29 20:45:08 -0700510 }
511
Alec Mouri1089aed2018-10-25 21:33:57 -0700512 template <typename SourceVariant>
513 void fillBuffer(half r, half g, half b, half a);
514
515 template <typename SourceVariant>
516 void fillRedBuffer();
517
518 template <typename SourceVariant>
519 void fillGreenBuffer();
520
521 template <typename SourceVariant>
522 void fillBlueBuffer();
523
524 template <typename SourceVariant>
525 void fillRedTransparentBuffer();
526
527 template <typename SourceVariant>
528 void fillRedOffsetBuffer();
529
530 template <typename SourceVariant>
531 void fillBufferPhysicalOffset();
532
533 template <typename SourceVariant>
Alec Mouri5a6d8572020-03-23 23:56:15 -0700534 void fillBufferCheckers(uint32_t rotation);
Alec Mouri1089aed2018-10-25 21:33:57 -0700535
536 template <typename SourceVariant>
537 void fillBufferCheckersRotate0();
538
539 template <typename SourceVariant>
540 void fillBufferCheckersRotate90();
541
542 template <typename SourceVariant>
543 void fillBufferCheckersRotate180();
544
545 template <typename SourceVariant>
546 void fillBufferCheckersRotate270();
547
548 template <typename SourceVariant>
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800549 void fillBufferWithLayerTransform();
550
551 template <typename SourceVariant>
Alec Mouri1089aed2018-10-25 21:33:57 -0700552 void fillBufferLayerTransform();
553
554 template <typename SourceVariant>
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800555 void fillBufferWithColorTransform();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800556
557 template <typename SourceVariant>
Alec Mouri1089aed2018-10-25 21:33:57 -0700558 void fillBufferColorTransform();
559
Alec Mouri7c94edb2018-12-03 21:23:26 -0800560 template <typename SourceVariant>
Sally Qi2019fd22021-11-22 10:19:04 -0800561 void fillBufferWithColorTransformAndSourceDataspace(const ui::Dataspace sourceDataspace);
562
563 template <typename SourceVariant>
564 void fillBufferColorTransformAndSourceDataspace();
565
566 template <typename SourceVariant>
567 void fillBufferWithColorTransformAndOutputDataspace(const ui::Dataspace outputDataspace);
568
569 template <typename SourceVariant>
570 void fillBufferColorTransformAndOutputDataspace();
571
572 template <typename SourceVariant>
KaiChieh Chuangda2845c2020-12-14 16:49:38 +0800573 void fillBufferWithColorTransformZeroLayerAlpha();
574
575 template <typename SourceVariant>
576 void fillBufferColorTransformZeroLayerAlpha();
577
578 template <typename SourceVariant>
Alec Mouri7c94edb2018-12-03 21:23:26 -0800579 void fillRedBufferWithRoundedCorners();
580
581 template <typename SourceVariant>
582 void fillBufferWithRoundedCorners();
583
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000584 template <typename SourceVariant>
Lucas Dupin19c8f0e2019-11-25 17:55:44 -0800585 void fillBufferAndBlurBackground();
586
587 template <typename SourceVariant>
Alec Mourie8489fd2021-04-29 16:08:56 -0700588 void fillSmallLayerAndBlurBackground();
589
590 template <typename SourceVariant>
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000591 void overlayCorners();
592
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800593 void fillRedBufferTextureTransform();
594
595 void fillBufferTextureTransform();
596
597 void fillRedBufferWithPremultiplyAlpha();
598
599 void fillBufferWithPremultiplyAlpha();
600
601 void fillRedBufferWithoutPremultiplyAlpha();
602
603 void fillBufferWithoutPremultiplyAlpha();
604
Alec Mouriac335532018-11-12 15:01:33 -0800605 void fillGreenColorBufferThenClearRegion();
606
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800607 template <typename SourceVariant>
608 void drawShadow(const renderengine::LayerSettings& castingLayer,
609 const renderengine::ShadowSettings& shadow, const ubyte4& casterColor,
610 const ubyte4& backgroundColor);
611
Alec Mouribd17b3b2020-12-17 11:08:30 -0800612 void drawShadowWithoutCaster(const FloatRect& castingBounds,
613 const renderengine::ShadowSettings& shadow,
614 const ubyte4& backgroundColor);
615
Alec Mouri5a493722022-01-26 16:43:02 -0800616 // Tonemaps grey values from sourceDataspace -> Display P3 and checks that GPU and CPU
617 // implementations are identical Also implicitly checks that the injected tonemap shader
618 // compiles
619 void tonemap(ui::Dataspace sourceDataspace, std::function<vec3(vec3)> eotf,
620 std::function<vec3(vec3, float)> scaleOotf);
621
Alec Mouric0aae732021-01-12 13:32:18 -0800622 void initializeRenderEngine();
623
624 std::unique_ptr<renderengine::RenderEngine> mRE;
Alec Mouria90a5702021-04-16 16:36:21 +0000625 std::shared_ptr<renderengine::ExternalTexture> mBuffer;
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800626
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800627 std::vector<uint32_t> mTexNames;
Alec Mouri6e57f682018-09-29 20:45:08 -0700628};
629
Alec Mouric0aae732021-01-12 13:32:18 -0800630void RenderEngineTest::initializeRenderEngine() {
631 const auto& renderEngineFactory = GetParam();
Alec Mouric16974e2022-09-13 17:35:48 +0000632 mRE = renderEngineFactory->createRenderEngine();
Alec Mouria90a5702021-04-16 16:36:21 +0000633 mBuffer = allocateDefaultBuffer();
Alec Mouric0aae732021-01-12 13:32:18 -0800634}
635
Alec Mouri1089aed2018-10-25 21:33:57 -0700636struct ColorSourceVariant {
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800637 static void fillColor(renderengine::LayerSettings& layer, half r, half g, half b,
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800638 RenderEngineTest* /*fixture*/) {
Alec Mouri1089aed2018-10-25 21:33:57 -0700639 layer.source.solidColor = half3(r, g, b);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800640 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700641 }
642};
643
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800644struct RelaxOpaqueBufferVariant {
645 static void setOpaqueBit(renderengine::LayerSettings& layer) {
646 layer.source.buffer.isOpaque = false;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800647 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800648 }
649
650 static uint8_t getAlphaChannel() { return 255; }
651};
652
653struct ForceOpaqueBufferVariant {
654 static void setOpaqueBit(renderengine::LayerSettings& layer) {
655 layer.source.buffer.isOpaque = true;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800656 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800657 }
658
659 static uint8_t getAlphaChannel() {
660 // The isOpaque bit will override the alpha channel, so this should be
661 // arbitrary.
Alec Mouric0aae732021-01-12 13:32:18 -0800662 return 50;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800663 }
664};
665
666template <typename OpaquenessVariant>
667struct BufferSourceVariant {
668 static void fillColor(renderengine::LayerSettings& layer, half r, half g, half b,
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800669 RenderEngineTest* fixture) {
Alec Mouria90a5702021-04-16 16:36:21 +0000670 const auto buf = fixture->allocateSourceBuffer(1, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800671 uint32_t texName;
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800672 fixture->mRE->genTextures(1, &texName);
673 fixture->mTexNames.push_back(texName);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800674
675 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +0000676 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
677 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800678
Alec Mouria90a5702021-04-16 16:36:21 +0000679 for (int32_t j = 0; j < buf->getBuffer()->getHeight(); j++) {
680 uint8_t* iter = pixels + (buf->getBuffer()->getStride() * j) * 4;
681 for (int32_t i = 0; i < buf->getBuffer()->getWidth(); i++) {
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800682 iter[0] = uint8_t(r * 255);
683 iter[1] = uint8_t(g * 255);
684 iter[2] = uint8_t(b * 255);
685 iter[3] = OpaquenessVariant::getAlphaChannel();
686 iter += 4;
687 }
688 }
689
Alec Mouria90a5702021-04-16 16:36:21 +0000690 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800691
692 layer.source.buffer.buffer = buf;
693 layer.source.buffer.textureName = texName;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800694 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800695 OpaquenessVariant::setOpaqueBit(layer);
696 }
697};
698
Alec Mouri1089aed2018-10-25 21:33:57 -0700699template <typename SourceVariant>
700void RenderEngineTest::fillBuffer(half r, half g, half b, half a) {
701 renderengine::DisplaySettings settings;
702 settings.physicalDisplay = fullscreenRect();
703 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800704 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700705
Sally Qi59a9f502021-10-12 18:53:23 +0000706 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700707
708 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800709 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700710 layer.geometry.boundaries = fullscreenRect().toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800711 SourceVariant::fillColor(layer, r, g, b, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700712 layer.alpha = a;
713
Sally Qi59a9f502021-10-12 18:53:23 +0000714 layers.push_back(layer);
Alec Mouri1089aed2018-10-25 21:33:57 -0700715
Alec Mouric0aae732021-01-12 13:32:18 -0800716 invokeDraw(settings, layers);
Alec Mouri1089aed2018-10-25 21:33:57 -0700717}
718
719template <typename SourceVariant>
720void RenderEngineTest::fillRedBuffer() {
721 fillBuffer<SourceVariant>(1.0f, 0.0f, 0.0f, 1.0f);
722 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
723}
724
725template <typename SourceVariant>
726void RenderEngineTest::fillGreenBuffer() {
727 fillBuffer<SourceVariant>(0.0f, 1.0f, 0.0f, 1.0f);
728 expectBufferColor(fullscreenRect(), 0, 255, 0, 255);
729}
730
731template <typename SourceVariant>
732void RenderEngineTest::fillBlueBuffer() {
733 fillBuffer<SourceVariant>(0.0f, 0.0f, 1.0f, 1.0f);
734 expectBufferColor(fullscreenRect(), 0, 0, 255, 255);
735}
736
737template <typename SourceVariant>
738void RenderEngineTest::fillRedTransparentBuffer() {
739 fillBuffer<SourceVariant>(1.0f, 0.0f, 0.0f, .2f);
740 expectBufferColor(fullscreenRect(), 51, 0, 0, 51);
741}
742
743template <typename SourceVariant>
744void RenderEngineTest::fillRedOffsetBuffer() {
745 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800746 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700747 settings.physicalDisplay = offsetRect();
748 settings.clip = offsetRectAtZero();
749
Sally Qi59a9f502021-10-12 18:53:23 +0000750 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700751
752 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800753 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700754 layer.geometry.boundaries = offsetRectAtZero().toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800755 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700756 layer.alpha = 1.0f;
757
Sally Qi59a9f502021-10-12 18:53:23 +0000758 layers.push_back(layer);
Alec Mouric0aae732021-01-12 13:32:18 -0800759 invokeDraw(settings, layers);
Alec Mouri1089aed2018-10-25 21:33:57 -0700760}
761
762template <typename SourceVariant>
763void RenderEngineTest::fillBufferPhysicalOffset() {
764 fillRedOffsetBuffer<SourceVariant>();
765
766 expectBufferColor(Rect(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_WIDTH,
767 DEFAULT_DISPLAY_HEIGHT),
768 255, 0, 0, 255);
769 Rect offsetRegionLeft(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_HEIGHT);
770 Rect offsetRegionTop(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_OFFSET);
771
772 expectBufferColor(offsetRegionLeft, 0, 0, 0, 0);
773 expectBufferColor(offsetRegionTop, 0, 0, 0, 0);
774}
775
776template <typename SourceVariant>
Alec Mouri5a6d8572020-03-23 23:56:15 -0700777void RenderEngineTest::fillBufferCheckers(uint32_t orientationFlag) {
Alec Mouri1089aed2018-10-25 21:33:57 -0700778 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800779 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700780 settings.physicalDisplay = fullscreenRect();
781 // Here logical space is 2x2
782 settings.clip = Rect(2, 2);
Alec Mouri5a6d8572020-03-23 23:56:15 -0700783 settings.orientation = orientationFlag;
Alec Mouri1089aed2018-10-25 21:33:57 -0700784
Sally Qi59a9f502021-10-12 18:53:23 +0000785 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700786
787 renderengine::LayerSettings layerOne;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800788 layerOne.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700789 Rect rectOne(0, 0, 1, 1);
790 layerOne.geometry.boundaries = rectOne.toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800791 SourceVariant::fillColor(layerOne, 1.0f, 0.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700792 layerOne.alpha = 1.0f;
793
794 renderengine::LayerSettings layerTwo;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800795 layerTwo.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700796 Rect rectTwo(0, 1, 1, 2);
797 layerTwo.geometry.boundaries = rectTwo.toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800798 SourceVariant::fillColor(layerTwo, 0.0f, 1.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700799 layerTwo.alpha = 1.0f;
800
801 renderengine::LayerSettings layerThree;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800802 layerThree.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700803 Rect rectThree(1, 0, 2, 1);
804 layerThree.geometry.boundaries = rectThree.toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800805 SourceVariant::fillColor(layerThree, 0.0f, 0.0f, 1.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700806 layerThree.alpha = 1.0f;
807
Sally Qi59a9f502021-10-12 18:53:23 +0000808 layers.push_back(layerOne);
809 layers.push_back(layerTwo);
810 layers.push_back(layerThree);
Alec Mouri1089aed2018-10-25 21:33:57 -0700811
Alec Mouric0aae732021-01-12 13:32:18 -0800812 invokeDraw(settings, layers);
Alec Mouri1089aed2018-10-25 21:33:57 -0700813}
814
815template <typename SourceVariant>
816void RenderEngineTest::fillBufferCheckersRotate0() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700817 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_0);
Alec Mouri1089aed2018-10-25 21:33:57 -0700818 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0,
819 255);
820 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
821 DEFAULT_DISPLAY_HEIGHT / 2),
822 0, 0, 255, 255);
823 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
824 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
825 0, 0, 0, 0);
826 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
827 DEFAULT_DISPLAY_HEIGHT),
828 0, 255, 0, 255);
829}
830
831template <typename SourceVariant>
832void RenderEngineTest::fillBufferCheckersRotate90() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700833 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_90);
Alec Mouri1089aed2018-10-25 21:33:57 -0700834 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 255, 0,
835 255);
836 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
837 DEFAULT_DISPLAY_HEIGHT / 2),
838 255, 0, 0, 255);
839 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
840 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
841 0, 0, 255, 255);
842 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
843 DEFAULT_DISPLAY_HEIGHT),
844 0, 0, 0, 0);
845}
846
847template <typename SourceVariant>
848void RenderEngineTest::fillBufferCheckersRotate180() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700849 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_180);
Alec Mouri1089aed2018-10-25 21:33:57 -0700850 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 0,
851 0);
852 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
853 DEFAULT_DISPLAY_HEIGHT / 2),
854 0, 255, 0, 255);
855 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
856 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
857 255, 0, 0, 255);
858 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
859 DEFAULT_DISPLAY_HEIGHT),
860 0, 0, 255, 255);
861}
862
863template <typename SourceVariant>
864void RenderEngineTest::fillBufferCheckersRotate270() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700865 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_270);
Alec Mouri1089aed2018-10-25 21:33:57 -0700866 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 255,
867 255);
868 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
869 DEFAULT_DISPLAY_HEIGHT / 2),
870 0, 0, 0, 0);
871 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
872 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
873 0, 255, 0, 255);
874 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
875 DEFAULT_DISPLAY_HEIGHT),
876 255, 0, 0, 255);
877}
878
879template <typename SourceVariant>
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800880void RenderEngineTest::fillBufferWithLayerTransform() {
Alec Mouri1089aed2018-10-25 21:33:57 -0700881 renderengine::DisplaySettings settings;
882 settings.physicalDisplay = fullscreenRect();
883 // Here logical space is 2x2
884 settings.clip = Rect(2, 2);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800885 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700886
Sally Qi59a9f502021-10-12 18:53:23 +0000887 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700888
889 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800890 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700891 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
892 // Translate one pixel diagonally
893 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 -0800894 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700895 layer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
896 layer.alpha = 1.0f;
897
Sally Qi59a9f502021-10-12 18:53:23 +0000898 layers.push_back(layer);
Alec Mouri1089aed2018-10-25 21:33:57 -0700899
Alec Mouric0aae732021-01-12 13:32:18 -0800900 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800901}
Alec Mouri1089aed2018-10-25 21:33:57 -0700902
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800903template <typename SourceVariant>
904void RenderEngineTest::fillBufferLayerTransform() {
905 fillBufferWithLayerTransform<SourceVariant>();
Alec Mouri1089aed2018-10-25 21:33:57 -0700906 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 0, 0);
907 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
908 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
909 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
910 255, 0, 0, 255);
911}
912
913template <typename SourceVariant>
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800914void RenderEngineTest::fillBufferWithColorTransform() {
Alec Mouri1089aed2018-10-25 21:33:57 -0700915 renderengine::DisplaySettings settings;
916 settings.physicalDisplay = fullscreenRect();
917 settings.clip = Rect(1, 1);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800918 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700919
Sally Qi59a9f502021-10-12 18:53:23 +0000920 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700921
922 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800923 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700924 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800925 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700926 layer.alpha = 1.0f;
927
928 // construct a fake color matrix
929 // annihilate green and blue channels
KaiChieh Chuang436fc192020-09-07 13:48:42 +0800930 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
Alec Mouri1089aed2018-10-25 21:33:57 -0700931 // set red channel to red + green
932 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
933
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800934 layer.alpha = 1.0f;
935 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
936
Sally Qi59a9f502021-10-12 18:53:23 +0000937 layers.push_back(layer);
Alec Mouri1089aed2018-10-25 21:33:57 -0700938
Alec Mouric0aae732021-01-12 13:32:18 -0800939 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800940}
Alec Mouri1089aed2018-10-25 21:33:57 -0700941
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800942template <typename SourceVariant>
Sally Qi2019fd22021-11-22 10:19:04 -0800943void RenderEngineTest::fillBufferWithColorTransformAndSourceDataspace(
944 const ui::Dataspace sourceDataspace) {
945 renderengine::DisplaySettings settings;
946 settings.physicalDisplay = fullscreenRect();
947 settings.clip = Rect(1, 1);
948 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
949
950 std::vector<renderengine::LayerSettings> layers;
951
952 renderengine::LayerSettings layer;
Sally Qi2019fd22021-11-22 10:19:04 -0800953 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
954 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
Alec Mouric16974e2022-09-13 17:35:48 +0000955 layer.sourceDataspace = sourceDataspace;
Sally Qi2019fd22021-11-22 10:19:04 -0800956 layer.alpha = 1.0f;
957
958 // construct a fake color matrix
959 // annihilate green and blue channels
960 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
961 // set red channel to red + green
962 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
963
964 layer.alpha = 1.0f;
965 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
966
967 layers.push_back(layer);
968
969 invokeDraw(settings, layers);
970}
971
972template <typename SourceVariant>
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800973void RenderEngineTest::fillBufferColorTransform() {
974 fillBufferWithColorTransform<SourceVariant>();
KaiChieh Chuang436fc192020-09-07 13:48:42 +0800975 expectBufferColor(fullscreenRect(), 172, 0, 0, 255, 1);
976}
977
978template <typename SourceVariant>
Sally Qi2019fd22021-11-22 10:19:04 -0800979void RenderEngineTest::fillBufferColorTransformAndSourceDataspace() {
980 unordered_map<ui::Dataspace, ubyte4> dataspaceToColorMap;
Alec Mouric16974e2022-09-13 17:35:48 +0000981 dataspaceToColorMap[ui::Dataspace::V0_BT709] = {77, 0, 0, 255};
982 dataspaceToColorMap[ui::Dataspace::BT2020] = {101, 0, 0, 255};
983 dataspaceToColorMap[ui::Dataspace::ADOBE_RGB] = {75, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -0800984 ui::Dataspace customizedDataspace = static_cast<ui::Dataspace>(
985 ui::Dataspace::STANDARD_BT709 | ui::Dataspace::TRANSFER_GAMMA2_2 |
986 ui::Dataspace::RANGE_FULL);
Alec Mouric16974e2022-09-13 17:35:48 +0000987 dataspaceToColorMap[customizedDataspace] = {61, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -0800988 for (const auto& [sourceDataspace, color] : dataspaceToColorMap) {
989 fillBufferWithColorTransformAndSourceDataspace<SourceVariant>(sourceDataspace);
990 expectBufferColor(fullscreenRect(), color.r, color.g, color.b, color.a, 1);
991 }
992}
993
994template <typename SourceVariant>
995void RenderEngineTest::fillBufferWithColorTransformAndOutputDataspace(
996 const ui::Dataspace outputDataspace) {
997 renderengine::DisplaySettings settings;
998 settings.physicalDisplay = fullscreenRect();
999 settings.clip = Rect(1, 1);
1000 settings.outputDataspace = outputDataspace;
1001
1002 std::vector<renderengine::LayerSettings> layers;
1003
1004 renderengine::LayerSettings layer;
1005 layer.sourceDataspace = ui::Dataspace::V0_SCRGB_LINEAR;
1006 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1007 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
1008 layer.alpha = 1.0f;
1009
1010 // construct a fake color matrix
1011 // annihilate green and blue channels
1012 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
1013 // set red channel to red + green
1014 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
1015
1016 layer.alpha = 1.0f;
1017 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1018
1019 layers.push_back(layer);
1020
1021 invokeDraw(settings, layers);
1022}
1023
1024template <typename SourceVariant>
1025void RenderEngineTest::fillBufferColorTransformAndOutputDataspace() {
1026 unordered_map<ui::Dataspace, ubyte4> dataspaceToColorMap;
Alec Mouric16974e2022-09-13 17:35:48 +00001027 dataspaceToColorMap[ui::Dataspace::V0_BT709] = {198, 0, 0, 255};
1028 dataspaceToColorMap[ui::Dataspace::BT2020] = {187, 0, 0, 255};
1029 dataspaceToColorMap[ui::Dataspace::ADOBE_RGB] = {192, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -08001030 ui::Dataspace customizedDataspace = static_cast<ui::Dataspace>(
1031 ui::Dataspace::STANDARD_BT709 | ui::Dataspace::TRANSFER_GAMMA2_6 |
1032 ui::Dataspace::RANGE_FULL);
Alec Mouric16974e2022-09-13 17:35:48 +00001033 dataspaceToColorMap[customizedDataspace] = {205, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -08001034 for (const auto& [outputDataspace, color] : dataspaceToColorMap) {
1035 fillBufferWithColorTransformAndOutputDataspace<SourceVariant>(outputDataspace);
1036 expectBufferColor(fullscreenRect(), color.r, color.g, color.b, color.a, 1);
1037 }
1038}
1039
1040template <typename SourceVariant>
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001041void RenderEngineTest::fillBufferWithColorTransformZeroLayerAlpha() {
1042 renderengine::DisplaySettings settings;
1043 settings.physicalDisplay = fullscreenRect();
1044 settings.clip = Rect(1, 1);
1045
Sally Qi59a9f502021-10-12 18:53:23 +00001046 std::vector<renderengine::LayerSettings> layers;
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001047
1048 renderengine::LayerSettings layer;
1049 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1050 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
1051 layer.alpha = 0;
1052
1053 // construct a fake color matrix
1054 // simple inverse color
1055 settings.colorTransform = mat4(-1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 1, 1, 1, 1);
1056
1057 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1058
Sally Qi59a9f502021-10-12 18:53:23 +00001059 layers.push_back(layer);
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001060
Alec Mouric0aae732021-01-12 13:32:18 -08001061 invokeDraw(settings, layers);
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001062}
1063
1064template <typename SourceVariant>
1065void RenderEngineTest::fillBufferColorTransformZeroLayerAlpha() {
1066 fillBufferWithColorTransformZeroLayerAlpha<SourceVariant>();
1067 expectBufferColor(fullscreenRect(), 0, 0, 0, 0);
1068}
1069
1070template <typename SourceVariant>
Alec Mouri7c94edb2018-12-03 21:23:26 -08001071void RenderEngineTest::fillRedBufferWithRoundedCorners() {
1072 renderengine::DisplaySettings settings;
1073 settings.physicalDisplay = fullscreenRect();
1074 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001075 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri7c94edb2018-12-03 21:23:26 -08001076
Sally Qi59a9f502021-10-12 18:53:23 +00001077 std::vector<renderengine::LayerSettings> layers;
Alec Mouri7c94edb2018-12-03 21:23:26 -08001078
1079 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001080 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri7c94edb2018-12-03 21:23:26 -08001081 layer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07001082 layer.geometry.roundedCornersRadius = {5.0f, 5.0f};
Alec Mouri7c94edb2018-12-03 21:23:26 -08001083 layer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
1084 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
1085 layer.alpha = 1.0f;
1086
Sally Qi59a9f502021-10-12 18:53:23 +00001087 layers.push_back(layer);
Alec Mouri7c94edb2018-12-03 21:23:26 -08001088
Alec Mouric0aae732021-01-12 13:32:18 -08001089 invokeDraw(settings, layers);
Alec Mouri7c94edb2018-12-03 21:23:26 -08001090}
1091
1092template <typename SourceVariant>
1093void RenderEngineTest::fillBufferWithRoundedCorners() {
1094 fillRedBufferWithRoundedCorners<SourceVariant>();
1095 // Corners should be ignored...
1096 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 0);
1097 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, 0, DEFAULT_DISPLAY_WIDTH, 1), 0, 0, 0, 0);
1098 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT - 1, 1, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
1099 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1,
1100 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1101 0, 0, 0, 0);
1102 // ...And the non-rounded portion should be red.
1103 // Other pixels may be anti-aliased, so let's not check those.
1104 expectBufferColor(Rect(5, 5, DEFAULT_DISPLAY_WIDTH - 5, DEFAULT_DISPLAY_HEIGHT - 5), 255, 0, 0,
1105 255);
1106}
1107
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001108template <typename SourceVariant>
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001109void RenderEngineTest::fillBufferAndBlurBackground() {
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001110 auto blurRadius = 50;
1111 auto center = DEFAULT_DISPLAY_WIDTH / 2;
1112
1113 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001114 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001115 settings.physicalDisplay = fullscreenRect();
1116 settings.clip = fullscreenRect();
1117
Sally Qi59a9f502021-10-12 18:53:23 +00001118 std::vector<renderengine::LayerSettings> layers;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001119
1120 renderengine::LayerSettings backgroundLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001121 backgroundLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001122 backgroundLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1123 SourceVariant::fillColor(backgroundLayer, 0.0f, 1.0f, 0.0f, this);
1124 backgroundLayer.alpha = 1.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001125 layers.emplace_back(backgroundLayer);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001126
1127 renderengine::LayerSettings leftLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001128 leftLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001129 leftLayer.geometry.boundaries =
1130 Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT).toFloatRect();
1131 SourceVariant::fillColor(leftLayer, 1.0f, 0.0f, 0.0f, this);
1132 leftLayer.alpha = 1.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001133 layers.emplace_back(leftLayer);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001134
1135 renderengine::LayerSettings blurLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001136 blurLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001137 blurLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1138 blurLayer.backgroundBlurRadius = blurRadius;
Derek Sollenbergerecb21462021-01-29 16:53:49 -05001139 SourceVariant::fillColor(blurLayer, 0.0f, 0.0f, 1.0f, this);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001140 blurLayer.alpha = 0;
Sally Qi59a9f502021-10-12 18:53:23 +00001141 layers.emplace_back(blurLayer);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001142
Alec Mouric0aae732021-01-12 13:32:18 -08001143 invokeDraw(settings, layers);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001144
Derek Sollenbergerecb21462021-01-29 16:53:49 -05001145 // solid color
1146 expectBufferColor(Rect(0, 0, 1, 1), 255, 0, 0, 255, 0 /* tolerance */);
1147
Derek Sollenbergerb3998372021-02-16 15:16:56 -05001148 if (mRE->supportsBackgroundBlur()) {
1149 // blurred color (downsampling should result in the center color being close to 128)
1150 expectBufferColor(Rect(center - 1, center - 5, center + 1, center + 5), 128, 128, 0, 255,
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001151 50 /* tolerance */);
Derek Sollenbergerb3998372021-02-16 15:16:56 -05001152 }
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001153}
1154
1155template <typename SourceVariant>
Alec Mourie8489fd2021-04-29 16:08:56 -07001156void RenderEngineTest::fillSmallLayerAndBlurBackground() {
1157 auto blurRadius = 50;
1158 renderengine::DisplaySettings settings;
1159 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1160 settings.physicalDisplay = fullscreenRect();
1161 settings.clip = fullscreenRect();
1162
Sally Qi59a9f502021-10-12 18:53:23 +00001163 std::vector<renderengine::LayerSettings> layers;
Alec Mourie8489fd2021-04-29 16:08:56 -07001164
1165 renderengine::LayerSettings backgroundLayer;
1166 backgroundLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1167 backgroundLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1168 SourceVariant::fillColor(backgroundLayer, 1.0f, 0.0f, 0.0f, this);
1169 backgroundLayer.alpha = 1.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001170 layers.push_back(backgroundLayer);
Alec Mourie8489fd2021-04-29 16:08:56 -07001171
1172 renderengine::LayerSettings blurLayer;
1173 blurLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1174 blurLayer.geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f);
1175 blurLayer.backgroundBlurRadius = blurRadius;
1176 SourceVariant::fillColor(blurLayer, 0.0f, 0.0f, 1.0f, this);
1177 blurLayer.alpha = 0;
Sally Qi59a9f502021-10-12 18:53:23 +00001178 layers.push_back(blurLayer);
Alec Mourie8489fd2021-04-29 16:08:56 -07001179
1180 invokeDraw(settings, layers);
1181
1182 // Give a generous tolerance - the blur rectangle is very small and this test is
1183 // mainly concerned with ensuring that there's no device failure.
1184 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT), 255, 0, 0, 255,
1185 40 /* tolerance */);
1186}
1187
1188template <typename SourceVariant>
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001189void RenderEngineTest::overlayCorners() {
1190 renderengine::DisplaySettings settings;
1191 settings.physicalDisplay = fullscreenRect();
1192 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001193 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001194
Sally Qi59a9f502021-10-12 18:53:23 +00001195 std::vector<renderengine::LayerSettings> layersFirst;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001196
1197 renderengine::LayerSettings layerOne;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001198 layerOne.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001199 layerOne.geometry.boundaries =
1200 FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH / 3.0, DEFAULT_DISPLAY_HEIGHT / 3.0);
1201 SourceVariant::fillColor(layerOne, 1.0f, 0.0f, 0.0f, this);
1202 layerOne.alpha = 0.2;
1203
Sally Qi59a9f502021-10-12 18:53:23 +00001204 layersFirst.push_back(layerOne);
Alec Mouric0aae732021-01-12 13:32:18 -08001205 invokeDraw(settings, layersFirst);
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001206 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3), 51, 0, 0, 51);
1207 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3 + 1, DEFAULT_DISPLAY_HEIGHT / 3 + 1,
1208 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1209 0, 0, 0, 0);
1210
Sally Qi59a9f502021-10-12 18:53:23 +00001211 std::vector<renderengine::LayerSettings> layersSecond;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001212 renderengine::LayerSettings layerTwo;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001213 layerTwo.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001214 layerTwo.geometry.boundaries =
1215 FloatRect(DEFAULT_DISPLAY_WIDTH / 3.0, DEFAULT_DISPLAY_HEIGHT / 3.0,
1216 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT);
1217 SourceVariant::fillColor(layerTwo, 0.0f, 1.0f, 0.0f, this);
1218 layerTwo.alpha = 1.0f;
1219
Sally Qi59a9f502021-10-12 18:53:23 +00001220 layersSecond.push_back(layerTwo);
Alec Mouric0aae732021-01-12 13:32:18 -08001221 invokeDraw(settings, layersSecond);
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001222
1223 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3), 0, 0, 0, 0);
1224 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3 + 1, DEFAULT_DISPLAY_HEIGHT / 3 + 1,
1225 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1226 0, 255, 0, 255);
1227}
1228
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001229void RenderEngineTest::fillRedBufferTextureTransform() {
1230 renderengine::DisplaySettings settings;
1231 settings.physicalDisplay = fullscreenRect();
1232 settings.clip = Rect(1, 1);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001233 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001234
Sally Qi59a9f502021-10-12 18:53:23 +00001235 std::vector<renderengine::LayerSettings> layers;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001236
1237 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001238 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001239 // Here will allocate a checker board texture, but transform texture
1240 // coordinates so that only the upper left is applied.
Alec Mouria90a5702021-04-16 16:36:21 +00001241 const auto buf = allocateSourceBuffer(2, 2);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001242 uint32_t texName;
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001243 RenderEngineTest::mRE->genTextures(1, &texName);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001244 this->mTexNames.push_back(texName);
1245
1246 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00001247 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1248 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001249 // Red top left, Green top right, Blue bottom left, Black bottom right
1250 pixels[0] = 255;
1251 pixels[1] = 0;
1252 pixels[2] = 0;
1253 pixels[3] = 255;
1254 pixels[4] = 0;
1255 pixels[5] = 255;
1256 pixels[6] = 0;
1257 pixels[7] = 255;
1258 pixels[8] = 0;
1259 pixels[9] = 0;
1260 pixels[10] = 255;
1261 pixels[11] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00001262 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001263
1264 layer.source.buffer.buffer = buf;
1265 layer.source.buffer.textureName = texName;
1266 // Transform coordinates to only be inside the red quadrant.
Alec Mouri4049b532021-10-15 20:59:33 -07001267 layer.source.buffer.textureTransform = mat4::scale(vec4(0.2f, 0.2f, 1.f, 1.f));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001268 layer.alpha = 1.0f;
1269 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1270
Sally Qi59a9f502021-10-12 18:53:23 +00001271 layers.push_back(layer);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001272
Alec Mouric0aae732021-01-12 13:32:18 -08001273 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001274}
1275
1276void RenderEngineTest::fillBufferTextureTransform() {
1277 fillRedBufferTextureTransform();
1278 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
1279}
1280
1281void RenderEngineTest::fillRedBufferWithPremultiplyAlpha() {
1282 renderengine::DisplaySettings settings;
1283 settings.physicalDisplay = fullscreenRect();
1284 // Here logical space is 1x1
1285 settings.clip = Rect(1, 1);
1286
Sally Qi59a9f502021-10-12 18:53:23 +00001287 std::vector<renderengine::LayerSettings> layers;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001288
1289 renderengine::LayerSettings layer;
Alec Mouria90a5702021-04-16 16:36:21 +00001290 const auto buf = allocateSourceBuffer(1, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001291 uint32_t texName;
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001292 RenderEngineTest::mRE->genTextures(1, &texName);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001293 this->mTexNames.push_back(texName);
1294
1295 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00001296 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1297 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001298 pixels[0] = 255;
1299 pixels[1] = 0;
1300 pixels[2] = 0;
1301 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00001302 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001303
1304 layer.source.buffer.buffer = buf;
1305 layer.source.buffer.textureName = texName;
1306 layer.source.buffer.usePremultipliedAlpha = true;
1307 layer.alpha = 0.5f;
1308 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1309
Sally Qi59a9f502021-10-12 18:53:23 +00001310 layers.push_back(layer);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001311
Alec Mouric0aae732021-01-12 13:32:18 -08001312 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001313}
1314
1315void RenderEngineTest::fillBufferWithPremultiplyAlpha() {
1316 fillRedBufferWithPremultiplyAlpha();
1317 expectBufferColor(fullscreenRect(), 128, 0, 0, 128);
1318}
1319
1320void RenderEngineTest::fillRedBufferWithoutPremultiplyAlpha() {
1321 renderengine::DisplaySettings settings;
1322 settings.physicalDisplay = fullscreenRect();
1323 // Here logical space is 1x1
1324 settings.clip = Rect(1, 1);
1325
Sally Qi59a9f502021-10-12 18:53:23 +00001326 std::vector<renderengine::LayerSettings> layers;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001327
1328 renderengine::LayerSettings layer;
Alec Mouria90a5702021-04-16 16:36:21 +00001329 const auto buf = allocateSourceBuffer(1, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001330 uint32_t texName;
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001331 RenderEngineTest::mRE->genTextures(1, &texName);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001332 this->mTexNames.push_back(texName);
1333
1334 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00001335 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1336 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001337 pixels[0] = 255;
1338 pixels[1] = 0;
1339 pixels[2] = 0;
1340 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00001341 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001342
1343 layer.source.buffer.buffer = buf;
1344 layer.source.buffer.textureName = texName;
1345 layer.source.buffer.usePremultipliedAlpha = false;
1346 layer.alpha = 0.5f;
1347 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1348
Sally Qi59a9f502021-10-12 18:53:23 +00001349 layers.push_back(layer);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001350
Alec Mouric0aae732021-01-12 13:32:18 -08001351 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001352}
1353
1354void RenderEngineTest::fillBufferWithoutPremultiplyAlpha() {
1355 fillRedBufferWithoutPremultiplyAlpha();
wukui16f3c0bb2020-08-05 20:35:29 +08001356 expectBufferColor(fullscreenRect(), 128, 0, 0, 128, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001357}
1358
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001359template <typename SourceVariant>
1360void RenderEngineTest::drawShadow(const renderengine::LayerSettings& castingLayer,
1361 const renderengine::ShadowSettings& shadow,
1362 const ubyte4& casterColor, const ubyte4& backgroundColor) {
1363 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001364 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001365 settings.physicalDisplay = fullscreenRect();
1366 settings.clip = fullscreenRect();
1367
Sally Qi59a9f502021-10-12 18:53:23 +00001368 std::vector<renderengine::LayerSettings> layers;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001369
1370 // add background layer
1371 renderengine::LayerSettings bgLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001372 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001373 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1374 ColorSourceVariant::fillColor(bgLayer, backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1375 backgroundColor.b / 255.0f, this);
1376 bgLayer.alpha = backgroundColor.a / 255.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001377 layers.push_back(bgLayer);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001378
1379 // add shadow layer
1380 renderengine::LayerSettings shadowLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001381 shadowLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001382 shadowLayer.geometry.boundaries = castingLayer.geometry.boundaries;
1383 shadowLayer.alpha = castingLayer.alpha;
1384 shadowLayer.shadow = shadow;
Sally Qi59a9f502021-10-12 18:53:23 +00001385 layers.push_back(shadowLayer);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001386
1387 // add layer casting the shadow
1388 renderengine::LayerSettings layer = castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001389 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001390 SourceVariant::fillColor(layer, casterColor.r / 255.0f, casterColor.g / 255.0f,
1391 casterColor.b / 255.0f, this);
Sally Qi59a9f502021-10-12 18:53:23 +00001392 layers.push_back(layer);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001393
Alec Mouric0aae732021-01-12 13:32:18 -08001394 invokeDraw(settings, layers);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001395}
1396
Alec Mouribd17b3b2020-12-17 11:08:30 -08001397void RenderEngineTest::drawShadowWithoutCaster(const FloatRect& castingBounds,
1398 const renderengine::ShadowSettings& shadow,
1399 const ubyte4& backgroundColor) {
1400 renderengine::DisplaySettings settings;
1401 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1402 settings.physicalDisplay = fullscreenRect();
1403 settings.clip = fullscreenRect();
1404
Sally Qi59a9f502021-10-12 18:53:23 +00001405 std::vector<renderengine::LayerSettings> layers;
Alec Mouribd17b3b2020-12-17 11:08:30 -08001406
1407 // add background layer
1408 renderengine::LayerSettings bgLayer;
1409 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1410 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1411 ColorSourceVariant::fillColor(bgLayer, backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1412 backgroundColor.b / 255.0f, this);
1413 bgLayer.alpha = backgroundColor.a / 255.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001414 layers.push_back(bgLayer);
Alec Mouribd17b3b2020-12-17 11:08:30 -08001415
1416 // add shadow layer
1417 renderengine::LayerSettings shadowLayer;
1418 shadowLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1419 shadowLayer.geometry.boundaries = castingBounds;
Derek Sollenbergerc31985e2021-05-18 16:38:17 -04001420 shadowLayer.skipContentDraw = true;
Alec Mouribd17b3b2020-12-17 11:08:30 -08001421 shadowLayer.alpha = 1.0f;
1422 ColorSourceVariant::fillColor(shadowLayer, 0, 0, 0, this);
1423 shadowLayer.shadow = shadow;
Sally Qi59a9f502021-10-12 18:53:23 +00001424 layers.push_back(shadowLayer);
Alec Mouribd17b3b2020-12-17 11:08:30 -08001425
Alec Mouric0aae732021-01-12 13:32:18 -08001426 invokeDraw(settings, layers);
Alec Mouribd17b3b2020-12-17 11:08:30 -08001427}
1428
Alec Mouri5a493722022-01-26 16:43:02 -08001429void RenderEngineTest::tonemap(ui::Dataspace sourceDataspace, std::function<vec3(vec3)> eotf,
1430 std::function<vec3(vec3, float)> scaleOotf) {
1431 constexpr int32_t kGreyLevels = 256;
1432
1433 const auto rect = Rect(0, 0, kGreyLevels, 1);
1434
1435 constexpr float kMaxLuminance = 750.f;
1436 constexpr float kCurrentLuminanceNits = 500.f;
1437 const renderengine::DisplaySettings display{
1438 .physicalDisplay = rect,
1439 .clip = rect,
1440 .maxLuminance = kMaxLuminance,
1441 .currentLuminanceNits = kCurrentLuminanceNits,
1442 .outputDataspace = ui::Dataspace::DISPLAY_P3,
1443 };
1444
1445 auto buf = std::make_shared<
1446 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07001447 ExternalTexture>(sp<GraphicBuffer>::make(kGreyLevels, 1,
1448 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1449 GRALLOC_USAGE_SW_READ_OFTEN |
1450 GRALLOC_USAGE_SW_WRITE_OFTEN |
1451 GRALLOC_USAGE_HW_RENDER |
1452 GRALLOC_USAGE_HW_TEXTURE,
1453 "input"),
Alec Mouri5a493722022-01-26 16:43:02 -08001454 *mRE,
1455 renderengine::impl::ExternalTexture::Usage::READABLE |
1456 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
1457 ASSERT_EQ(0, buf->getBuffer()->initCheck());
1458 {
1459 uint8_t* pixels;
1460 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1461 reinterpret_cast<void**>(&pixels));
1462
1463 uint8_t color = 0;
1464 for (int32_t j = 0; j < buf->getBuffer()->getHeight(); j++) {
1465 uint8_t* dest = pixels + (buf->getBuffer()->getStride() * j * 4);
1466 for (int32_t i = 0; i < buf->getBuffer()->getWidth(); i++) {
1467 dest[0] = color;
1468 dest[1] = color;
1469 dest[2] = color;
1470 dest[3] = 255;
1471 color++;
1472 dest += 4;
1473 }
1474 }
1475 buf->getBuffer()->unlock();
1476 }
1477
1478 mBuffer = std::make_shared<
1479 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07001480 ExternalTexture>(sp<GraphicBuffer>::make(kGreyLevels, 1,
1481 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1482 GRALLOC_USAGE_SW_READ_OFTEN |
1483 GRALLOC_USAGE_SW_WRITE_OFTEN |
1484 GRALLOC_USAGE_HW_RENDER |
1485 GRALLOC_USAGE_HW_TEXTURE,
1486 "output"),
Alec Mouri5a493722022-01-26 16:43:02 -08001487 *mRE,
1488 renderengine::impl::ExternalTexture::Usage::READABLE |
1489 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
1490 ASSERT_EQ(0, mBuffer->getBuffer()->initCheck());
1491
1492 const renderengine::LayerSettings layer{.geometry.boundaries = rect.toFloatRect(),
1493 .source =
1494 renderengine::PixelSource{
1495 .buffer =
1496 renderengine::Buffer{
1497 .buffer =
1498 std::move(buf),
1499 .usePremultipliedAlpha =
1500 true,
1501 },
1502 },
1503 .alpha = 1.0f,
1504 .sourceDataspace = sourceDataspace};
1505
1506 std::vector<renderengine::LayerSettings> layers{layer};
1507 invokeDraw(display, layers);
1508
1509 ColorSpace displayP3 = ColorSpace::DisplayP3();
1510 ColorSpace bt2020 = ColorSpace::BT2020();
1511
1512 tonemap::Metadata metadata{.displayMaxLuminance = 750.0f};
1513
1514 auto generator = [=](Point location) {
1515 const double normColor = static_cast<double>(location.x) / (kGreyLevels - 1);
1516 const vec3 rgb = vec3(normColor, normColor, normColor);
1517
1518 const vec3 linearRGB = eotf(rgb);
1519
1520 const vec3 xyz = bt2020.getRGBtoXYZ() * linearRGB;
1521
1522 const vec3 scaledXYZ = scaleOotf(xyz, kCurrentLuminanceNits);
Alec Mouri196b0f22022-03-04 22:13:48 +00001523 const auto gains =
Alec Mouri5a493722022-01-26 16:43:02 -08001524 tonemap::getToneMapper()
1525 ->lookupTonemapGain(static_cast<aidl::android::hardware::graphics::common::
1526 Dataspace>(sourceDataspace),
1527 static_cast<aidl::android::hardware::graphics::common::
1528 Dataspace>(
1529 ui::Dataspace::DISPLAY_P3),
Alec Mouri196b0f22022-03-04 22:13:48 +00001530 {tonemap::
1531 Color{.linearRGB =
1532 scaleOotf(linearRGB,
1533 kCurrentLuminanceNits),
1534 .xyz = scaledXYZ}},
Alec Mouri5a493722022-01-26 16:43:02 -08001535 metadata);
Alec Mouri196b0f22022-03-04 22:13:48 +00001536 EXPECT_EQ(1, gains.size());
1537 const double gain = gains.front();
Alec Mouri5a493722022-01-26 16:43:02 -08001538 const vec3 normalizedXYZ = scaledXYZ * gain / metadata.displayMaxLuminance;
1539
1540 const vec3 targetRGB = OETF_sRGB(displayP3.getXYZtoRGB() * normalizedXYZ) * 255;
1541 return ubyte4(static_cast<uint8_t>(targetRGB.r), static_cast<uint8_t>(targetRGB.g),
1542 static_cast<uint8_t>(targetRGB.b), 255);
1543 };
1544
1545 expectBufferColor(Rect(kGreyLevels, 1), generator, 2);
1546}
1547
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001548INSTANTIATE_TEST_SUITE_P(PerRenderEngineType, RenderEngineTest,
Alec Mouric16974e2022-09-13 17:35:48 +00001549 testing::Values(std::make_shared<SkiaGLESRenderEngineFactory>(),
Alec Mouri47bcb072023-08-15 02:02:49 +00001550 std::make_shared<SkiaVkRenderEngineFactory>()));
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001551
1552TEST_P(RenderEngineTest, drawLayers_noLayersToDraw) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001553 if (!GetParam()->typeSupported()) {
1554 GTEST_SKIP();
1555 }
Alec Mouric0aae732021-01-12 13:32:18 -08001556 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001557 drawEmptyLayers();
1558}
1559
Sally Qi1fed86e2022-06-23 15:33:52 -07001560TEST_P(RenderEngineTest, drawLayers_fillRedBufferAndEmptyBuffer) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001561 if (!GetParam()->typeSupported()) {
1562 GTEST_SKIP();
1563 }
Sally Qi1fed86e2022-06-23 15:33:52 -07001564 initializeRenderEngine();
1565 renderengine::DisplaySettings settings;
1566 settings.physicalDisplay = fullscreenRect();
1567 settings.clip = fullscreenRect();
1568 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1569
1570 // add a red layer
1571 renderengine::LayerSettings layerOne{
1572 .geometry.boundaries = fullscreenRect().toFloatRect(),
1573 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
1574 .alpha = 1.f,
1575 };
1576
1577 std::vector<renderengine::LayerSettings> layersFirst{layerOne};
1578 invokeDraw(settings, layersFirst);
1579 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
1580
1581 // re-draw with an empty layer above it, and we get a transparent black one
1582 std::vector<renderengine::LayerSettings> layersSecond;
1583 invokeDraw(settings, layersSecond);
1584 expectBufferColor(fullscreenRect(), 0, 0, 0, 0);
1585}
1586
Ana Krulec07b98df2021-01-07 14:38:40 -08001587TEST_P(RenderEngineTest, drawLayers_withoutBuffers_withColorTransform) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001588 if (!GetParam()->typeSupported()) {
1589 GTEST_SKIP();
1590 }
Alec Mouria90a5702021-04-16 16:36:21 +00001591 initializeRenderEngine();
Ana Krulec07b98df2021-01-07 14:38:40 -08001592
1593 renderengine::DisplaySettings settings;
1594 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1595 settings.physicalDisplay = fullscreenRect();
1596 settings.clip = fullscreenRect();
1597
1598 // 255, 255, 255, 255 is full opaque white.
Alec Mouri4049b532021-10-15 20:59:33 -07001599 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
1600 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Ana Krulec07b98df2021-01-07 14:38:40 -08001601 // Create layer with given color.
1602 renderengine::LayerSettings bgLayer;
1603 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1604 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1605 bgLayer.source.solidColor = half3(backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1606 backgroundColor.b / 255.0f);
1607 bgLayer.alpha = backgroundColor.a / 255.0f;
1608 // Transform the red color.
1609 bgLayer.colorTransform = mat4(-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
1610
Sally Qi59a9f502021-10-12 18:53:23 +00001611 std::vector<renderengine::LayerSettings> layers;
1612 layers.push_back(bgLayer);
Ana Krulec07b98df2021-01-07 14:38:40 -08001613
Alec Mouric0aae732021-01-12 13:32:18 -08001614 invokeDraw(settings, layers);
Ana Krulec07b98df2021-01-07 14:38:40 -08001615
1616 // Expect to see full opaque pixel (with inverted red from the transform).
Alec Mouric0aae732021-01-12 13:32:18 -08001617 expectBufferColor(Rect(0, 0, 10, 10), 0.f, backgroundColor.g, backgroundColor.b,
Ana Krulec07b98df2021-01-07 14:38:40 -08001618 backgroundColor.a);
1619}
1620
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001621TEST_P(RenderEngineTest, drawLayers_nullOutputBuffer) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001622 if (!GetParam()->typeSupported()) {
1623 GTEST_SKIP();
1624 }
Alec Mouric0aae732021-01-12 13:32:18 -08001625 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001626
Alec Mourid43ccab2019-03-13 12:23:45 -07001627 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001628 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Sally Qi59a9f502021-10-12 18:53:23 +00001629 std::vector<renderengine::LayerSettings> layers;
Alec Mourid43ccab2019-03-13 12:23:45 -07001630 renderengine::LayerSettings layer;
1631 layer.geometry.boundaries = fullscreenRect().toFloatRect();
1632 BufferSourceVariant<ForceOpaqueBufferVariant>::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
Sally Qi59a9f502021-10-12 18:53:23 +00001633 layers.push_back(layer);
Patrick Williams2e9748f2022-08-09 22:48:18 +00001634 ftl::Future<FenceResult> future =
Sally Qi4cabdd02021-08-05 16:45:57 -07001635 mRE->drawLayers(settings, layers, nullptr, true, base::unique_fd());
Alec Mourid43ccab2019-03-13 12:23:45 -07001636
Patrick Williams2e9748f2022-08-09 22:48:18 +00001637 ASSERT_TRUE(future.valid());
1638 auto result = future.get();
1639 ASSERT_FALSE(result.ok());
1640 ASSERT_EQ(BAD_VALUE, result.error());
Alec Mourid43ccab2019-03-13 12:23:45 -07001641}
1642
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001643TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001644 if (!GetParam()->typeSupported()) {
1645 GTEST_SKIP();
1646 }
Alec Mouric0aae732021-01-12 13:32:18 -08001647 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001648 fillRedBuffer<ColorSourceVariant>();
1649}
1650
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001651TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001652 if (!GetParam()->typeSupported()) {
1653 GTEST_SKIP();
1654 }
Alec Mouric0aae732021-01-12 13:32:18 -08001655 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001656 fillGreenBuffer<ColorSourceVariant>();
1657}
1658
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001659TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001660 if (!GetParam()->typeSupported()) {
1661 GTEST_SKIP();
1662 }
Alec Mouric0aae732021-01-12 13:32:18 -08001663 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001664 fillBlueBuffer<ColorSourceVariant>();
1665}
1666
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001667TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001668 if (!GetParam()->typeSupported()) {
1669 GTEST_SKIP();
1670 }
Alec Mouric0aae732021-01-12 13:32:18 -08001671 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001672 fillRedTransparentBuffer<ColorSourceVariant>();
1673}
1674
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001675TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001676 if (!GetParam()->typeSupported()) {
1677 GTEST_SKIP();
1678 }
Alec Mouric0aae732021-01-12 13:32:18 -08001679 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001680 fillBufferPhysicalOffset<ColorSourceVariant>();
1681}
1682
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001683TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001684 if (!GetParam()->typeSupported()) {
1685 GTEST_SKIP();
1686 }
Alec Mouric0aae732021-01-12 13:32:18 -08001687 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001688 fillBufferCheckersRotate0<ColorSourceVariant>();
1689}
1690
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001691TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001692 if (!GetParam()->typeSupported()) {
1693 GTEST_SKIP();
1694 }
Alec Mouric0aae732021-01-12 13:32:18 -08001695 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001696 fillBufferCheckersRotate90<ColorSourceVariant>();
1697}
1698
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001699TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001700 if (!GetParam()->typeSupported()) {
1701 GTEST_SKIP();
1702 }
Alec Mouric0aae732021-01-12 13:32:18 -08001703 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001704 fillBufferCheckersRotate180<ColorSourceVariant>();
1705}
1706
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001707TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001708 if (!GetParam()->typeSupported()) {
1709 GTEST_SKIP();
1710 }
Alec Mouric0aae732021-01-12 13:32:18 -08001711 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001712 fillBufferCheckersRotate270<ColorSourceVariant>();
1713}
1714
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001715TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001716 if (!GetParam()->typeSupported()) {
1717 GTEST_SKIP();
1718 }
Alec Mouric0aae732021-01-12 13:32:18 -08001719 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001720 fillBufferLayerTransform<ColorSourceVariant>();
1721}
1722
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001723TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001724 if (!GetParam()->typeSupported()) {
1725 GTEST_SKIP();
1726 }
Alec Mouric0aae732021-01-12 13:32:18 -08001727 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08001728 fillBufferColorTransform<ColorSourceVariant>();
1729}
1730
Sally Qi2019fd22021-11-22 10:19:04 -08001731TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_sourceDataspace) {
1732 const auto& renderEngineFactory = GetParam();
1733 // skip for non color management
Alec Mouri47bcb072023-08-15 02:02:49 +00001734 if (!renderEngineFactory->typeSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001735 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001736 }
1737
1738 initializeRenderEngine();
1739 fillBufferColorTransformAndSourceDataspace<ColorSourceVariant>();
1740}
1741
1742TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_outputDataspace) {
1743 const auto& renderEngineFactory = GetParam();
1744 // skip for non color management
Alec Mouri47bcb072023-08-15 02:02:49 +00001745 if (!renderEngineFactory->typeSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001746 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001747 }
1748
1749 initializeRenderEngine();
1750 fillBufferColorTransformAndOutputDataspace<ColorSourceVariant>();
1751}
1752
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001753TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001754 if (!GetParam()->typeSupported()) {
1755 GTEST_SKIP();
1756 }
Alec Mouric0aae732021-01-12 13:32:18 -08001757 initializeRenderEngine();
Alec Mouri7c94edb2018-12-03 21:23:26 -08001758 fillBufferWithRoundedCorners<ColorSourceVariant>();
1759}
1760
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001761TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001762 if (!GetParam()->typeSupported()) {
1763 GTEST_SKIP();
1764 }
Alec Mouric0aae732021-01-12 13:32:18 -08001765 initializeRenderEngine();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001766 fillBufferColorTransformZeroLayerAlpha<ColorSourceVariant>();
1767}
1768
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001769TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001770 if (!GetParam()->typeSupported()) {
1771 GTEST_SKIP();
1772 }
Alec Mouric0aae732021-01-12 13:32:18 -08001773 initializeRenderEngine();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001774 fillBufferAndBlurBackground<ColorSourceVariant>();
1775}
1776
Alec Mourie8489fd2021-04-29 16:08:56 -07001777TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001778 if (!GetParam()->typeSupported()) {
1779 GTEST_SKIP();
1780 }
Alec Mourie8489fd2021-04-29 16:08:56 -07001781 initializeRenderEngine();
1782 fillSmallLayerAndBlurBackground<ColorSourceVariant>();
1783}
1784
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001785TEST_P(RenderEngineTest, drawLayers_overlayCorners_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001786 if (!GetParam()->typeSupported()) {
1787 GTEST_SKIP();
1788 }
Alec Mouric0aae732021-01-12 13:32:18 -08001789 initializeRenderEngine();
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001790 overlayCorners<ColorSourceVariant>();
1791}
1792
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001793TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001794 if (!GetParam()->typeSupported()) {
1795 GTEST_SKIP();
1796 }
Alec Mouric0aae732021-01-12 13:32:18 -08001797 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001798 fillRedBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1799}
1800
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001801TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001802 if (!GetParam()->typeSupported()) {
1803 GTEST_SKIP();
1804 }
Alec Mouric0aae732021-01-12 13:32:18 -08001805 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001806 fillGreenBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1807}
1808
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001809TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001810 if (!GetParam()->typeSupported()) {
1811 GTEST_SKIP();
1812 }
Alec Mouric0aae732021-01-12 13:32:18 -08001813 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001814 fillBlueBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1815}
1816
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001817TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001818 if (!GetParam()->typeSupported()) {
1819 GTEST_SKIP();
1820 }
Alec Mouric0aae732021-01-12 13:32:18 -08001821 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001822 fillRedTransparentBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1823}
1824
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001825TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001826 if (!GetParam()->typeSupported()) {
1827 GTEST_SKIP();
1828 }
Alec Mouric0aae732021-01-12 13:32:18 -08001829 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001830 fillBufferPhysicalOffset<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1831}
1832
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001833TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001834 if (!GetParam()->typeSupported()) {
1835 GTEST_SKIP();
1836 }
Alec Mouric0aae732021-01-12 13:32:18 -08001837 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001838 fillBufferCheckersRotate0<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1839}
1840
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001841TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001842 if (!GetParam()->typeSupported()) {
1843 GTEST_SKIP();
1844 }
Alec Mouric0aae732021-01-12 13:32:18 -08001845 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001846 fillBufferCheckersRotate90<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1847}
1848
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001849TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001850 if (!GetParam()->typeSupported()) {
1851 GTEST_SKIP();
1852 }
Alec Mouric0aae732021-01-12 13:32:18 -08001853 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001854 fillBufferCheckersRotate180<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1855}
1856
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001857TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001858 if (!GetParam()->typeSupported()) {
1859 GTEST_SKIP();
1860 }
Alec Mouric0aae732021-01-12 13:32:18 -08001861 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001862 fillBufferCheckersRotate270<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1863}
1864
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001865TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001866 if (!GetParam()->typeSupported()) {
1867 GTEST_SKIP();
1868 }
Alec Mouric0aae732021-01-12 13:32:18 -08001869 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001870 fillBufferLayerTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1871}
1872
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001873TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001874 if (!GetParam()->typeSupported()) {
1875 GTEST_SKIP();
1876 }
Alec Mouric0aae732021-01-12 13:32:18 -08001877 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08001878 fillBufferColorTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1879}
1880
Sally Qi2019fd22021-11-22 10:19:04 -08001881TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndSourceDataspace_opaqueBufferSource) {
1882 const auto& renderEngineFactory = GetParam();
1883 // skip for non color management
Alec Mouri47bcb072023-08-15 02:02:49 +00001884 if (!renderEngineFactory->typeSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001885 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001886 }
1887
1888 initializeRenderEngine();
1889 fillBufferColorTransformAndSourceDataspace<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1890}
1891
1892TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndOutputDataspace_opaqueBufferSource) {
1893 const auto& renderEngineFactory = GetParam();
1894 // skip for non color management
Alec Mouri47bcb072023-08-15 02:02:49 +00001895 if (!renderEngineFactory->typeSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001896 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001897 }
1898
1899 initializeRenderEngine();
1900 fillBufferColorTransformAndOutputDataspace<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1901}
1902
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001903TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001904 if (!GetParam()->typeSupported()) {
1905 GTEST_SKIP();
1906 }
Alec Mouric0aae732021-01-12 13:32:18 -08001907 initializeRenderEngine();
Alec Mouri7c94edb2018-12-03 21:23:26 -08001908 fillBufferWithRoundedCorners<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1909}
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001910
Alec Mouric0aae732021-01-12 13:32:18 -08001911TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001912 if (!GetParam()->typeSupported()) {
1913 GTEST_SKIP();
1914 }
Alec Mouric0aae732021-01-12 13:32:18 -08001915 initializeRenderEngine();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001916 fillBufferColorTransformZeroLayerAlpha<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1917}
Alec Mouri7c94edb2018-12-03 21:23:26 -08001918
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001919TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001920 if (!GetParam()->typeSupported()) {
1921 GTEST_SKIP();
1922 }
Alec Mouric0aae732021-01-12 13:32:18 -08001923 initializeRenderEngine();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001924 fillBufferAndBlurBackground<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1925}
1926
Alec Mourie8489fd2021-04-29 16:08:56 -07001927TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001928 if (!GetParam()->typeSupported()) {
1929 GTEST_SKIP();
1930 }
Alec Mourie8489fd2021-04-29 16:08:56 -07001931 initializeRenderEngine();
1932 fillSmallLayerAndBlurBackground<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1933}
1934
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001935TEST_P(RenderEngineTest, drawLayers_overlayCorners_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001936 if (!GetParam()->typeSupported()) {
1937 GTEST_SKIP();
1938 }
Alec Mouric0aae732021-01-12 13:32:18 -08001939 initializeRenderEngine();
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001940 overlayCorners<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1941}
1942
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001943TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001944 if (!GetParam()->typeSupported()) {
1945 GTEST_SKIP();
1946 }
Alec Mouric0aae732021-01-12 13:32:18 -08001947 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001948 fillRedBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1949}
1950
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001951TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001952 if (!GetParam()->typeSupported()) {
1953 GTEST_SKIP();
1954 }
Alec Mouric0aae732021-01-12 13:32:18 -08001955 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001956 fillGreenBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1957}
1958
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001959TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001960 if (!GetParam()->typeSupported()) {
1961 GTEST_SKIP();
1962 }
Alec Mouric0aae732021-01-12 13:32:18 -08001963 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001964 fillBlueBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1965}
1966
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001967TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001968 if (!GetParam()->typeSupported()) {
1969 GTEST_SKIP();
1970 }
Alec Mouric0aae732021-01-12 13:32:18 -08001971 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001972 fillRedTransparentBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1973}
1974
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001975TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001976 if (!GetParam()->typeSupported()) {
1977 GTEST_SKIP();
1978 }
Alec Mouric0aae732021-01-12 13:32:18 -08001979 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001980 fillBufferPhysicalOffset<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1981}
1982
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001983TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001984 if (!GetParam()->typeSupported()) {
1985 GTEST_SKIP();
1986 }
Alec Mouric0aae732021-01-12 13:32:18 -08001987 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001988 fillBufferCheckersRotate0<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1989}
1990
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001991TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001992 if (!GetParam()->typeSupported()) {
1993 GTEST_SKIP();
1994 }
Alec Mouric0aae732021-01-12 13:32:18 -08001995 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001996 fillBufferCheckersRotate90<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1997}
1998
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001999TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002000 if (!GetParam()->typeSupported()) {
2001 GTEST_SKIP();
2002 }
Alec Mouric0aae732021-01-12 13:32:18 -08002003 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002004 fillBufferCheckersRotate180<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2005}
2006
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002007TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002008 if (!GetParam()->typeSupported()) {
2009 GTEST_SKIP();
2010 }
Alec Mouric0aae732021-01-12 13:32:18 -08002011 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002012 fillBufferCheckersRotate270<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2013}
2014
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002015TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002016 if (!GetParam()->typeSupported()) {
2017 GTEST_SKIP();
2018 }
Alec Mouric0aae732021-01-12 13:32:18 -08002019 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002020 fillBufferLayerTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2021}
2022
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002023TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002024 if (!GetParam()->typeSupported()) {
2025 GTEST_SKIP();
2026 }
Alec Mouric0aae732021-01-12 13:32:18 -08002027 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08002028 fillBufferColorTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2029}
2030
Sally Qi2019fd22021-11-22 10:19:04 -08002031TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndSourceDataspace_bufferSource) {
2032 const auto& renderEngineFactory = GetParam();
2033 // skip for non color management
Alec Mouri47bcb072023-08-15 02:02:49 +00002034 if (!renderEngineFactory->typeSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00002035 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08002036 }
2037
2038 initializeRenderEngine();
2039 fillBufferColorTransformAndSourceDataspace<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2040}
2041
2042TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndOutputDataspace_bufferSource) {
2043 const auto& renderEngineFactory = GetParam();
2044 // skip for non color management
Alec Mouri47bcb072023-08-15 02:02:49 +00002045 if (!renderEngineFactory->typeSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00002046 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08002047 }
2048
2049 initializeRenderEngine();
2050 fillBufferColorTransformAndOutputDataspace<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2051}
2052
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002053TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002054 if (!GetParam()->typeSupported()) {
2055 GTEST_SKIP();
2056 }
Alec Mouric0aae732021-01-12 13:32:18 -08002057 initializeRenderEngine();
Alec Mouri7c94edb2018-12-03 21:23:26 -08002058 fillBufferWithRoundedCorners<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2059}
2060
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08002061TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002062 if (!GetParam()->typeSupported()) {
2063 GTEST_SKIP();
2064 }
Alec Mouric0aae732021-01-12 13:32:18 -08002065 initializeRenderEngine();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08002066 fillBufferColorTransformZeroLayerAlpha<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2067}
2068
Nathaniel Nifong53494f32021-04-30 14:05:39 -04002069TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002070 if (!GetParam()->typeSupported()) {
2071 GTEST_SKIP();
2072 }
Alec Mouric0aae732021-01-12 13:32:18 -08002073 initializeRenderEngine();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08002074 fillBufferAndBlurBackground<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2075}
2076
Alec Mourie8489fd2021-04-29 16:08:56 -07002077TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002078 if (!GetParam()->typeSupported()) {
2079 GTEST_SKIP();
2080 }
Alec Mourie8489fd2021-04-29 16:08:56 -07002081 initializeRenderEngine();
2082 fillSmallLayerAndBlurBackground<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2083}
2084
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002085TEST_P(RenderEngineTest, drawLayers_overlayCorners_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002086 if (!GetParam()->typeSupported()) {
2087 GTEST_SKIP();
2088 }
Alec Mouric0aae732021-01-12 13:32:18 -08002089 initializeRenderEngine();
Alec Mourie7d1d4a2019-02-05 01:13:46 +00002090 overlayCorners<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2091}
2092
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002093TEST_P(RenderEngineTest, drawLayers_fillBufferTextureTransform) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002094 if (!GetParam()->typeSupported()) {
2095 GTEST_SKIP();
2096 }
Alec Mouric0aae732021-01-12 13:32:18 -08002097 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002098 fillBufferTextureTransform();
2099}
2100
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002101TEST_P(RenderEngineTest, drawLayers_fillBuffer_premultipliesAlpha) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002102 if (!GetParam()->typeSupported()) {
2103 GTEST_SKIP();
2104 }
Alec Mouric0aae732021-01-12 13:32:18 -08002105 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002106 fillBufferWithPremultiplyAlpha();
2107}
2108
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002109TEST_P(RenderEngineTest, drawLayers_fillBuffer_withoutPremultiplyingAlpha) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002110 if (!GetParam()->typeSupported()) {
2111 GTEST_SKIP();
2112 }
Alec Mouric0aae732021-01-12 13:32:18 -08002113 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002114 fillBufferWithoutPremultiplyAlpha();
2115}
2116
Alec Mouribd17b3b2020-12-17 11:08:30 -08002117TEST_P(RenderEngineTest, drawLayers_fillShadow_castsWithoutCasterLayer) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002118 if (!GetParam()->typeSupported()) {
2119 GTEST_SKIP();
2120 }
Alec Mouric0aae732021-01-12 13:32:18 -08002121 initializeRenderEngine();
Alec Mouribd17b3b2020-12-17 11:08:30 -08002122
Alec Mouri4049b532021-10-15 20:59:33 -07002123 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2124 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Alec Mouribd17b3b2020-12-17 11:08:30 -08002125 const float shadowLength = 5.0f;
2126 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2127 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2128 renderengine::ShadowSettings settings =
2129 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2130 false /* casterIsTranslucent */);
2131
2132 drawShadowWithoutCaster(casterBounds.toFloatRect(), settings, backgroundColor);
2133 expectShadowColorWithoutCaster(casterBounds.toFloatRect(), settings, backgroundColor);
2134}
2135
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002136TEST_P(RenderEngineTest, drawLayers_fillShadow_casterLayerMinSize) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002137 if (!GetParam()->typeSupported()) {
2138 GTEST_SKIP();
2139 }
Alec Mouric0aae732021-01-12 13:32:18 -08002140 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002141
Alec Mouri4049b532021-10-15 20:59:33 -07002142 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2143 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2144 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2145 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002146 const float shadowLength = 5.0f;
2147 Rect casterBounds(1, 1);
2148 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2149 renderengine::LayerSettings castingLayer;
2150 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2151 castingLayer.alpha = 1.0f;
2152 renderengine::ShadowSettings settings =
2153 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2154 false /* casterIsTranslucent */);
2155
2156 drawShadow<ColorSourceVariant>(castingLayer, settings, casterColor, backgroundColor);
2157 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2158}
2159
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002160TEST_P(RenderEngineTest, drawLayers_fillShadow_casterColorLayer) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002161 if (!GetParam()->typeSupported()) {
2162 GTEST_SKIP();
2163 }
Alec Mouric0aae732021-01-12 13:32:18 -08002164 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002165
Alec Mouri4049b532021-10-15 20:59:33 -07002166 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2167 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2168 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2169 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002170 const float shadowLength = 5.0f;
2171 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2172 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2173 renderengine::LayerSettings castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002174 castingLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002175 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2176 castingLayer.alpha = 1.0f;
2177 renderengine::ShadowSettings settings =
2178 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2179 false /* casterIsTranslucent */);
2180
2181 drawShadow<ColorSourceVariant>(castingLayer, settings, casterColor, backgroundColor);
2182 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2183}
2184
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002185TEST_P(RenderEngineTest, drawLayers_fillShadow_casterOpaqueBufferLayer) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002186 if (!GetParam()->typeSupported()) {
2187 GTEST_SKIP();
2188 }
Alec Mouric0aae732021-01-12 13:32:18 -08002189 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002190
Alec Mouri4049b532021-10-15 20:59:33 -07002191 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2192 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2193 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2194 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002195 const float shadowLength = 5.0f;
2196 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2197 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2198 renderengine::LayerSettings castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002199 castingLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002200 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2201 castingLayer.alpha = 1.0f;
2202 renderengine::ShadowSettings settings =
2203 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2204 false /* casterIsTranslucent */);
2205
2206 drawShadow<BufferSourceVariant<ForceOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2207 backgroundColor);
2208 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2209}
2210
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002211TEST_P(RenderEngineTest, drawLayers_fillShadow_casterWithRoundedCorner) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002212 if (!GetParam()->typeSupported()) {
2213 GTEST_SKIP();
2214 }
Alec Mouric0aae732021-01-12 13:32:18 -08002215 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002216
Alec Mouri4049b532021-10-15 20:59:33 -07002217 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2218 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2219 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2220 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002221 const float shadowLength = 5.0f;
2222 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2223 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2224 renderengine::LayerSettings castingLayer;
2225 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002226 castingLayer.geometry.roundedCornersRadius = {3.0f, 3.0f};
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002227 castingLayer.geometry.roundedCornersCrop = casterBounds.toFloatRect();
2228 castingLayer.alpha = 1.0f;
2229 renderengine::ShadowSettings settings =
2230 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2231 false /* casterIsTranslucent */);
2232
2233 drawShadow<BufferSourceVariant<ForceOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2234 backgroundColor);
2235 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2236}
2237
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002238TEST_P(RenderEngineTest, drawLayers_fillShadow_translucentCasterWithAlpha) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002239 if (!GetParam()->typeSupported()) {
2240 GTEST_SKIP();
2241 }
Alec Mouric0aae732021-01-12 13:32:18 -08002242 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002243
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002244 const ubyte4 casterColor(255, 0, 0, 255);
2245 const ubyte4 backgroundColor(255, 255, 255, 255);
2246 const float shadowLength = 5.0f;
2247 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2248 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2249 renderengine::LayerSettings castingLayer;
2250 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2251 castingLayer.alpha = 0.5f;
2252 renderengine::ShadowSettings settings =
2253 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2254 true /* casterIsTranslucent */);
2255
2256 drawShadow<BufferSourceVariant<RelaxOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2257 backgroundColor);
2258
2259 // verify only the background since the shadow will draw behind the caster
2260 const float shadowInset = settings.length * -1.0f;
2261 const Rect casterWithShadow =
2262 Rect(casterBounds).inset(shadowInset, shadowInset, shadowInset, shadowInset);
2263 const Region backgroundRegion = Region(fullscreenRect()).subtractSelf(casterWithShadow);
2264 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
2265 backgroundColor.a);
2266}
2267
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002268TEST_P(RenderEngineTest, cleanupPostRender_cleansUpOnce) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002269 if (!GetParam()->typeSupported()) {
2270 GTEST_SKIP();
2271 }
Alec Mouric0aae732021-01-12 13:32:18 -08002272 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002273
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002274 renderengine::DisplaySettings settings;
2275 settings.physicalDisplay = fullscreenRect();
2276 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002277 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002278
Sally Qi59a9f502021-10-12 18:53:23 +00002279 std::vector<renderengine::LayerSettings> layers;
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002280 renderengine::LayerSettings layer;
2281 layer.geometry.boundaries = fullscreenRect().toFloatRect();
2282 BufferSourceVariant<ForceOpaqueBufferVariant>::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
2283 layer.alpha = 1.0;
Sally Qi59a9f502021-10-12 18:53:23 +00002284 layers.push_back(layer);
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002285
Patrick Williams2e9748f2022-08-09 22:48:18 +00002286 ftl::Future<FenceResult> futureOne =
Sally Qi4cabdd02021-08-05 16:45:57 -07002287 mRE->drawLayers(settings, layers, mBuffer, true, base::unique_fd());
Patrick Williams2e9748f2022-08-09 22:48:18 +00002288 ASSERT_TRUE(futureOne.valid());
2289 auto resultOne = futureOne.get();
2290 ASSERT_TRUE(resultOne.ok());
2291 auto fenceOne = resultOne.value();
Sally Qi4cabdd02021-08-05 16:45:57 -07002292
Patrick Williams2e9748f2022-08-09 22:48:18 +00002293 ftl::Future<FenceResult> futureTwo =
2294 mRE->drawLayers(settings, layers, mBuffer, true, base::unique_fd(fenceOne->dup()));
2295 ASSERT_TRUE(futureTwo.valid());
2296 auto resultTwo = futureTwo.get();
2297 ASSERT_TRUE(resultTwo.ok());
2298 auto fenceTwo = resultTwo.value();
2299 fenceTwo->waitForever(LOG_TAG);
Derek Sollenbergerec411212021-08-25 10:54:47 -04002300
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002301 // Only cleanup the first time.
Ian Elliott1f0911e2022-09-09 16:31:47 -06002302 if (mRE->canSkipPostRenderCleanup()) {
2303 // Skia's Vk backend may keep the texture alive beyond drawLayersInternal, so
2304 // it never gets added to the cleanup list. In those cases, we can skip.
2305 EXPECT_TRUE(GetParam()->type() == renderengine::RenderEngine::RenderEngineType::SKIA_VK);
2306 } else {
2307 mRE->cleanupPostRender();
2308 EXPECT_TRUE(mRE->canSkipPostRenderCleanup());
2309 }
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002310}
2311
Ana Krulecf9a15d92020-12-11 08:35:00 -08002312TEST_P(RenderEngineTest, testRoundedCornersCrop) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002313 if (!GetParam()->typeSupported()) {
2314 GTEST_SKIP();
2315 }
Alec Mouric0aae732021-01-12 13:32:18 -08002316 initializeRenderEngine();
Ana Krulecf9a15d92020-12-11 08:35:00 -08002317
2318 renderengine::DisplaySettings settings;
2319 settings.physicalDisplay = fullscreenRect();
2320 settings.clip = fullscreenRect();
2321 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2322
Sally Qi59a9f502021-10-12 18:53:23 +00002323 std::vector<renderengine::LayerSettings> layers;
Ana Krulecf9a15d92020-12-11 08:35:00 -08002324
2325 renderengine::LayerSettings redLayer;
2326 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2327 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002328 redLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
2329
Ana Krulecf9a15d92020-12-11 08:35:00 -08002330 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2331 // Red background.
2332 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2333 redLayer.alpha = 1.0f;
2334
Sally Qi59a9f502021-10-12 18:53:23 +00002335 layers.push_back(redLayer);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002336
2337 // Green layer with 1/3 size.
2338 renderengine::LayerSettings greenLayer;
2339 greenLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2340 greenLayer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002341 greenLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
Ana Krulecf9a15d92020-12-11 08:35:00 -08002342 // Bottom right corner is not going to be rounded.
2343 greenLayer.geometry.roundedCornersCrop =
2344 Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3, DEFAULT_DISPLAY_HEIGHT,
2345 DEFAULT_DISPLAY_HEIGHT)
2346 .toFloatRect();
2347 greenLayer.source.solidColor = half3(0.0f, 1.0f, 0.0f);
2348 greenLayer.alpha = 1.0f;
2349
Sally Qi59a9f502021-10-12 18:53:23 +00002350 layers.push_back(greenLayer);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002351
Alec Mouric0aae732021-01-12 13:32:18 -08002352 invokeDraw(settings, layers);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002353
2354 // Corners should be ignored...
2355 // Screen size: width is 128, height is 256.
2356 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 0);
2357 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, 0, DEFAULT_DISPLAY_WIDTH, 1), 0, 0, 0, 0);
2358 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT - 1, 1, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
2359 // Bottom right corner is kept out of the clipping, and it's green.
2360 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1,
2361 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
2362 0, 255, 0, 255);
2363}
2364
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002365TEST_P(RenderEngineTest, testRoundedCornersParentCrop) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002366 if (!GetParam()->typeSupported()) {
2367 GTEST_SKIP();
2368 }
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002369 initializeRenderEngine();
2370
2371 renderengine::DisplaySettings settings;
2372 settings.physicalDisplay = fullscreenRect();
2373 settings.clip = fullscreenRect();
2374 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2375
Sally Qi59a9f502021-10-12 18:53:23 +00002376 std::vector<renderengine::LayerSettings> layers;
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002377
2378 renderengine::LayerSettings redLayer;
2379 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2380 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002381 redLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002382 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2383 // Red background.
2384 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2385 redLayer.alpha = 1.0f;
2386
Sally Qi59a9f502021-10-12 18:53:23 +00002387 layers.push_back(redLayer);
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002388
2389 // Green layer with 1/2 size with parent crop rect.
2390 renderengine::LayerSettings greenLayer = redLayer;
2391 greenLayer.geometry.boundaries =
2392 FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT / 2);
2393 greenLayer.source.solidColor = half3(0.0f, 1.0f, 0.0f);
2394
Sally Qi59a9f502021-10-12 18:53:23 +00002395 layers.push_back(greenLayer);
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002396
2397 invokeDraw(settings, layers);
2398
2399 // Due to roundedCornersRadius, the corners are untouched.
2400 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2401 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2402 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2403 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2404
2405 // top middle should be green and the bottom middle red
2406 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, 0), 0, 255, 0, 255);
2407 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0, 255);
2408
2409 // the bottom edge of the green layer should not be rounded
2410 expectBufferColor(Point(0, (DEFAULT_DISPLAY_HEIGHT / 2) - 1), 0, 255, 0, 255);
2411}
2412
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002413TEST_P(RenderEngineTest, testRoundedCornersParentCropSmallBounds) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002414 if (!GetParam()->typeSupported()) {
2415 GTEST_SKIP();
2416 }
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002417 initializeRenderEngine();
2418
2419 renderengine::DisplaySettings settings;
2420 settings.physicalDisplay = fullscreenRect();
2421 settings.clip = fullscreenRect();
2422 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2423
Sally Qi59a9f502021-10-12 18:53:23 +00002424 std::vector<renderengine::LayerSettings> layers;
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002425
2426 renderengine::LayerSettings redLayer;
2427 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2428 redLayer.geometry.boundaries = FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, 32);
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002429 redLayer.geometry.roundedCornersRadius = {64.0f, 64.0f};
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002430 redLayer.geometry.roundedCornersCrop = FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, 128);
2431 // Red background.
2432 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2433 redLayer.alpha = 1.0f;
2434
Sally Qi59a9f502021-10-12 18:53:23 +00002435 layers.push_back(redLayer);
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002436 invokeDraw(settings, layers);
2437
2438 // Due to roundedCornersRadius, the top corners are untouched.
2439 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2440 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2441
2442 // ensure that the entire height of the red layer was clipped by the rounded corners crop.
2443 expectBufferColor(Point(0, 31), 0, 0, 0, 0);
2444 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 31), 0, 0, 0, 0);
2445
2446 // the bottom middle should be red
2447 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, 31), 255, 0, 0, 255);
2448}
2449
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002450TEST_P(RenderEngineTest, testRoundedCornersXY) {
2451 if (GetParam()->type() != renderengine::RenderEngine::RenderEngineType::SKIA_GL) {
2452 GTEST_SKIP();
2453 }
2454
2455 initializeRenderEngine();
2456
2457 renderengine::DisplaySettings settings;
2458 settings.physicalDisplay = fullscreenRect();
2459 settings.clip = fullscreenRect();
2460 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2461
2462 std::vector<renderengine::LayerSettings> layers;
2463
2464 renderengine::LayerSettings redLayer;
2465 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2466 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
2467 redLayer.geometry.roundedCornersRadius = {5.0f, 20.0f};
2468 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2469 // Red background.
2470 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2471 redLayer.alpha = 1.0f;
2472
2473 layers.push_back(redLayer);
2474
2475 invokeDraw(settings, layers);
2476
2477 // Due to roundedCornersRadius, the corners are untouched.
2478 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2479 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2480 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2481 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2482
2483 // Y-axis draws a larger radius, check that its untouched as well
2484 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 5), 0, 0, 0, 0);
2485 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 5), 0, 0, 0, 0);
2486 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 5), 0, 0, 0, 0);
2487 expectBufferColor(Point(0, 5), 0, 0, 0, 0);
2488
2489 // middle should be red
2490 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0, 255);
2491}
2492
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002493TEST_P(RenderEngineTest, testClear) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002494 if (!GetParam()->typeSupported()) {
2495 GTEST_SKIP();
2496 }
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002497 initializeRenderEngine();
2498
2499 const auto rect = fullscreenRect();
2500 const renderengine::DisplaySettings display{
2501 .physicalDisplay = rect,
2502 .clip = rect,
2503 };
2504
2505 const renderengine::LayerSettings redLayer{
2506 .geometry.boundaries = rect.toFloatRect(),
2507 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
2508 .alpha = 1.0f,
2509 };
2510
2511 // This mimics prepareClearClientComposition. This layer should overwrite
2512 // the redLayer, so that the buffer is transparent, rather than red.
2513 const renderengine::LayerSettings clearLayer{
2514 .geometry.boundaries = rect.toFloatRect(),
2515 .source.solidColor = half3(0.0f, 0.0f, 0.0f),
2516 .alpha = 0.0f,
2517 .disableBlending = true,
2518 };
2519
Sally Qi59a9f502021-10-12 18:53:23 +00002520 std::vector<renderengine::LayerSettings> layers{redLayer, clearLayer};
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002521 invokeDraw(display, layers);
2522 expectBufferColor(rect, 0, 0, 0, 0);
2523}
2524
2525TEST_P(RenderEngineTest, testDisableBlendingBuffer) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002526 if (!GetParam()->typeSupported()) {
2527 GTEST_SKIP();
2528 }
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002529 initializeRenderEngine();
2530
2531 const auto rect = Rect(0, 0, 1, 1);
2532 const renderengine::DisplaySettings display{
2533 .physicalDisplay = rect,
2534 .clip = rect,
2535 };
2536
2537 const renderengine::LayerSettings redLayer{
2538 .geometry.boundaries = rect.toFloatRect(),
2539 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
2540 .alpha = 1.0f,
2541 };
2542
2543 // The next layer will overwrite redLayer with a GraphicBuffer that is green
2544 // applied with a translucent alpha.
Alec Mouria90a5702021-04-16 16:36:21 +00002545 const auto buf = allocateSourceBuffer(1, 1);
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002546 {
2547 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00002548 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2549 reinterpret_cast<void**>(&pixels));
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002550 pixels[0] = 0;
2551 pixels[1] = 255;
2552 pixels[2] = 0;
2553 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00002554 buf->getBuffer()->unlock();
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002555 }
2556
2557 const renderengine::LayerSettings greenLayer{
2558 .geometry.boundaries = rect.toFloatRect(),
2559 .source =
2560 renderengine::PixelSource{
2561 .buffer =
2562 renderengine::Buffer{
2563 .buffer = buf,
2564 .usePremultipliedAlpha = true,
2565 },
2566 },
2567 .alpha = 0.5f,
2568 .disableBlending = true,
2569 };
2570
Sally Qi59a9f502021-10-12 18:53:23 +00002571 std::vector<renderengine::LayerSettings> layers{redLayer, greenLayer};
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002572 invokeDraw(display, layers);
2573 expectBufferColor(rect, 0, 128, 0, 128);
2574}
2575
Tianhao Yao67dd7122022-02-22 17:48:33 +00002576TEST_P(RenderEngineTest, testBorder) {
2577 if (GetParam()->type() != renderengine::RenderEngine::RenderEngineType::SKIA_GL) {
2578 GTEST_SKIP();
2579 }
2580
Tianhao Yao67dd7122022-02-22 17:48:33 +00002581 initializeRenderEngine();
2582
2583 const ui::Dataspace dataspace = ui::Dataspace::V0_SRGB;
2584
2585 const auto displayRect = Rect(1080, 2280);
2586 renderengine::DisplaySettings display{
2587 .physicalDisplay = displayRect,
2588 .clip = displayRect,
2589 .outputDataspace = dataspace,
2590 };
2591 display.borderInfoList.clear();
2592 renderengine::BorderRenderInfo info;
2593 info.combinedRegion = Region(Rect(99, 99, 199, 199));
Tianhao Yao10cea3c2022-03-30 01:37:22 +00002594 info.width = 20.0f;
2595 info.color = half4{1.0f, 128.0f / 255.0f, 0.0f, 1.0f};
Tianhao Yao67dd7122022-02-22 17:48:33 +00002596 display.borderInfoList.emplace_back(info);
2597
2598 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2599 const renderengine::LayerSettings greenLayer{
2600 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2601 .source =
2602 renderengine::PixelSource{
2603 .buffer =
2604 renderengine::Buffer{
2605 .buffer = greenBuffer,
2606 .usePremultipliedAlpha = true,
2607 },
2608 },
2609 .alpha = 1.0f,
2610 .sourceDataspace = dataspace,
2611 .whitePointNits = 200.f,
2612 };
2613
2614 std::vector<renderengine::LayerSettings> layers;
2615 layers.emplace_back(greenLayer);
2616 invokeDraw(display, layers);
2617
2618 expectBufferColor(Rect(99, 99, 101, 101), 255, 128, 0, 255, 1);
2619}
2620
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002621TEST_P(RenderEngineTest, testDimming) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002622 if (!GetParam()->typeSupported()) {
2623 GTEST_SKIP();
2624 }
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002625 initializeRenderEngine();
2626
Alec Mouri85065692022-03-18 00:58:26 +00002627 const ui::Dataspace dataspace = ui::Dataspace::V0_SRGB_LINEAR;
2628
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002629 const auto displayRect = Rect(3, 1);
2630 const renderengine::DisplaySettings display{
2631 .physicalDisplay = displayRect,
2632 .clip = displayRect,
Alec Mouri85065692022-03-18 00:58:26 +00002633 .outputDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002634 .targetLuminanceNits = 1000.f,
2635 };
2636
2637 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2638 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2639 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2640
2641 const renderengine::LayerSettings greenLayer{
2642 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2643 .source =
2644 renderengine::PixelSource{
2645 .buffer =
2646 renderengine::Buffer{
2647 .buffer = greenBuffer,
2648 .usePremultipliedAlpha = true,
2649 },
2650 },
2651 .alpha = 1.0f,
Alec Mouri85065692022-03-18 00:58:26 +00002652 .sourceDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002653 .whitePointNits = 200.f,
2654 };
2655
2656 const renderengine::LayerSettings blueLayer{
2657 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2658 .source =
2659 renderengine::PixelSource{
2660 .buffer =
2661 renderengine::Buffer{
2662 .buffer = blueBuffer,
2663 .usePremultipliedAlpha = true,
2664 },
2665 },
2666 .alpha = 1.0f,
Alec Mouri85065692022-03-18 00:58:26 +00002667 .sourceDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002668 .whitePointNits = 1000.f / 51.f,
2669 };
2670
2671 const renderengine::LayerSettings redLayer{
2672 .geometry.boundaries = FloatRect(2.f, 0.f, 3.f, 1.f),
2673 .source =
2674 renderengine::PixelSource{
2675 .buffer =
2676 renderengine::Buffer{
2677 .buffer = redBuffer,
2678 .usePremultipliedAlpha = true,
2679 },
2680 },
2681 .alpha = 1.0f,
Alec Mouri85065692022-03-18 00:58:26 +00002682 .sourceDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002683 // When the white point is not set for a layer, just ignore it and treat it as the same
2684 // as the max layer
2685 .whitePointNits = -1.f,
2686 };
2687
2688 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer, redLayer};
2689 invokeDraw(display, layers);
2690
2691 expectBufferColor(Rect(1, 1), 0, 51, 0, 255, 1);
2692 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 5, 255, 1);
2693 expectBufferColor(Rect(2, 0, 3, 1), 51, 0, 0, 255, 1);
2694}
2695
Alec Mouri85065692022-03-18 00:58:26 +00002696TEST_P(RenderEngineTest, testDimming_inGammaSpace) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002697 if (!GetParam()->typeSupported()) {
2698 GTEST_SKIP();
2699 }
Alec Mouri85065692022-03-18 00:58:26 +00002700 initializeRenderEngine();
2701
2702 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2703 ui::Dataspace::TRANSFER_GAMMA2_2 |
2704 ui::Dataspace::RANGE_FULL);
2705
2706 const auto displayRect = Rect(3, 1);
2707 const renderengine::DisplaySettings display{
2708 .physicalDisplay = displayRect,
2709 .clip = displayRect,
2710 .outputDataspace = dataspace,
2711 .targetLuminanceNits = 1000.f,
2712 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2713 };
2714
2715 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2716 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2717 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2718
2719 const renderengine::LayerSettings greenLayer{
2720 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2721 .source =
2722 renderengine::PixelSource{
2723 .buffer =
2724 renderengine::Buffer{
2725 .buffer = greenBuffer,
2726 .usePremultipliedAlpha = true,
2727 },
2728 },
2729 .alpha = 1.0f,
2730 .sourceDataspace = dataspace,
2731 .whitePointNits = 200.f,
2732 };
2733
2734 const renderengine::LayerSettings blueLayer{
2735 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2736 .source =
2737 renderengine::PixelSource{
2738 .buffer =
2739 renderengine::Buffer{
2740 .buffer = blueBuffer,
2741 .usePremultipliedAlpha = true,
2742 },
2743 },
2744 .alpha = 1.0f,
2745 .sourceDataspace = dataspace,
2746 .whitePointNits = 1000.f / 51.f,
2747 };
2748
2749 const renderengine::LayerSettings redLayer{
2750 .geometry.boundaries = FloatRect(2.f, 0.f, 3.f, 1.f),
2751 .source =
2752 renderengine::PixelSource{
2753 .buffer =
2754 renderengine::Buffer{
2755 .buffer = redBuffer,
2756 .usePremultipliedAlpha = true,
2757 },
2758 },
2759 .alpha = 1.0f,
2760 .sourceDataspace = dataspace,
2761 // When the white point is not set for a layer, just ignore it and treat it as the same
2762 // as the max layer
2763 .whitePointNits = -1.f,
2764 };
2765
2766 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer, redLayer};
2767 invokeDraw(display, layers);
2768
2769 expectBufferColor(Rect(1, 1), 0, 122, 0, 255, 1);
2770 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 42, 255, 1);
2771 expectBufferColor(Rect(2, 0, 3, 1), 122, 0, 0, 255, 1);
2772}
2773
Alec Mouri9bcd1d12022-04-21 22:16:56 +00002774TEST_P(RenderEngineTest, testDimming_inGammaSpace_withDisplayColorTransform) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002775 if (!GetParam()->typeSupported()) {
2776 GTEST_SKIP();
2777 }
Alec Mouri9bcd1d12022-04-21 22:16:56 +00002778 initializeRenderEngine();
2779
2780 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2781 ui::Dataspace::TRANSFER_GAMMA2_2 |
2782 ui::Dataspace::RANGE_FULL);
2783
2784 const auto displayRect = Rect(3, 1);
2785 const renderengine::DisplaySettings display{
2786 .physicalDisplay = displayRect,
2787 .clip = displayRect,
2788 .outputDataspace = dataspace,
2789 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
2790 .targetLuminanceNits = 1000.f,
2791 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2792 };
2793
2794 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2795 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2796 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2797
2798 const renderengine::LayerSettings greenLayer{
2799 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2800 .source =
2801 renderengine::PixelSource{
2802 .buffer =
2803 renderengine::Buffer{
2804 .buffer = greenBuffer,
2805 .usePremultipliedAlpha = true,
2806 },
2807 },
2808 .alpha = 1.0f,
2809 .sourceDataspace = dataspace,
2810 .whitePointNits = 200.f,
2811 };
2812
2813 const renderengine::LayerSettings redLayer{
2814 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2815 .source =
2816 renderengine::PixelSource{
2817 .buffer =
2818 renderengine::Buffer{
2819 .buffer = redBuffer,
2820 .usePremultipliedAlpha = true,
2821 },
2822 },
2823 .alpha = 1.0f,
2824 .sourceDataspace = dataspace,
2825 // When the white point is not set for a layer, just ignore it and treat it as the same
2826 // as the max layer
2827 .whitePointNits = -1.f,
2828 };
2829
2830 std::vector<renderengine::LayerSettings> layers{greenLayer, redLayer};
2831 invokeDraw(display, layers);
2832
2833 expectBufferColor(Rect(1, 1), 0, 0, 0, 255, 1);
2834 expectBufferColor(Rect(1, 0, 2, 1), 0, 122, 0, 255, 1);
2835}
2836
2837TEST_P(RenderEngineTest, testDimming_inGammaSpace_withDisplayColorTransform_deviceHandles) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002838 if (!GetParam()->typeSupported()) {
2839 GTEST_SKIP();
2840 }
Alec Mouri9bcd1d12022-04-21 22:16:56 +00002841 initializeRenderEngine();
2842
2843 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2844 ui::Dataspace::TRANSFER_GAMMA2_2 |
2845 ui::Dataspace::RANGE_FULL);
2846
2847 const auto displayRect = Rect(3, 1);
2848 const renderengine::DisplaySettings display{
2849 .physicalDisplay = displayRect,
2850 .clip = displayRect,
2851 .outputDataspace = dataspace,
2852 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
2853 .deviceHandlesColorTransform = true,
2854 .targetLuminanceNits = 1000.f,
2855 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2856 };
2857
2858 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2859 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2860 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2861
2862 const renderengine::LayerSettings greenLayer{
2863 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2864 .source =
2865 renderengine::PixelSource{
2866 .buffer =
2867 renderengine::Buffer{
2868 .buffer = greenBuffer,
2869 .usePremultipliedAlpha = true,
2870 },
2871 },
2872 .alpha = 1.0f,
2873 .sourceDataspace = dataspace,
2874 .whitePointNits = 200.f,
2875 };
2876
2877 const renderengine::LayerSettings redLayer{
2878 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2879 .source =
2880 renderengine::PixelSource{
2881 .buffer =
2882 renderengine::Buffer{
2883 .buffer = redBuffer,
2884 .usePremultipliedAlpha = true,
2885 },
2886 },
2887 .alpha = 1.0f,
2888 .sourceDataspace = dataspace,
2889 // When the white point is not set for a layer, just ignore it and treat it as the same
2890 // as the max layer
2891 .whitePointNits = -1.f,
2892 };
2893
2894 std::vector<renderengine::LayerSettings> layers{greenLayer, redLayer};
2895 invokeDraw(display, layers);
2896
2897 expectBufferColor(Rect(1, 1), 0, 122, 0, 255, 1);
2898 expectBufferColor(Rect(1, 0, 2, 1), 122, 0, 0, 255, 1);
2899}
2900
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002901TEST_P(RenderEngineTest, testDimming_withoutTargetLuminance) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002902 if (!GetParam()->typeSupported()) {
2903 GTEST_SKIP();
2904 }
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002905 initializeRenderEngine();
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002906
2907 const auto displayRect = Rect(2, 1);
2908 const renderengine::DisplaySettings display{
2909 .physicalDisplay = displayRect,
2910 .clip = displayRect,
2911 .outputDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2912 .targetLuminanceNits = -1.f,
2913 };
2914
2915 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2916 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2917
2918 const renderengine::LayerSettings greenLayer{
2919 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2920 .source =
2921 renderengine::PixelSource{
2922 .buffer =
2923 renderengine::Buffer{
2924 .buffer = greenBuffer,
2925 .usePremultipliedAlpha = true,
2926 },
2927 },
2928 .alpha = 1.0f,
2929 .sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2930 .whitePointNits = 200.f,
2931 };
2932
2933 const renderengine::LayerSettings blueLayer{
2934 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2935 .source =
2936 renderengine::PixelSource{
2937 .buffer =
2938 renderengine::Buffer{
2939 .buffer = blueBuffer,
2940 .usePremultipliedAlpha = true,
2941 },
2942 },
2943 .alpha = 1.0f,
2944 .sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2945 .whitePointNits = 1000.f,
2946 };
2947
2948 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer};
2949 invokeDraw(display, layers);
2950
2951 expectBufferColor(Rect(1, 1), 0, 51, 0, 255, 1);
2952 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 255, 255);
2953}
2954
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002955TEST_P(RenderEngineTest, test_isOpaque) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002956 if (!GetParam()->typeSupported()) {
2957 GTEST_SKIP();
2958 }
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002959 initializeRenderEngine();
2960
2961 const auto rect = Rect(0, 0, 1, 1);
2962 const renderengine::DisplaySettings display{
2963 .physicalDisplay = rect,
2964 .clip = rect,
2965 .outputDataspace = ui::Dataspace::DISPLAY_P3,
2966 };
2967
2968 // Create an unpremul buffer that is green with no alpha. Using isOpaque
2969 // should make the green show.
2970 const auto buf = allocateSourceBuffer(1, 1);
2971 {
2972 uint8_t* pixels;
2973 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2974 reinterpret_cast<void**>(&pixels));
2975 pixels[0] = 0;
2976 pixels[1] = 255;
2977 pixels[2] = 0;
2978 pixels[3] = 0;
2979 buf->getBuffer()->unlock();
2980 }
2981
2982 const renderengine::LayerSettings greenLayer{
2983 .geometry.boundaries = rect.toFloatRect(),
2984 .source =
2985 renderengine::PixelSource{
2986 .buffer =
2987 renderengine::Buffer{
2988 .buffer = buf,
2989 // Although the pixels are not
2990 // premultiplied in practice, this
2991 // matches the input we see.
2992 .usePremultipliedAlpha = true,
2993 .isOpaque = true,
2994 },
2995 },
2996 .alpha = 1.0f,
2997 };
2998
Sally Qi59a9f502021-10-12 18:53:23 +00002999 std::vector<renderengine::LayerSettings> layers{greenLayer};
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04003000 invokeDraw(display, layers);
3001
Alec Mouri47bcb072023-08-15 02:02:49 +00003002 expectBufferColor(rect, 117, 251, 76, 255);
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04003003}
Alec Mouri4049b532021-10-15 20:59:33 -07003004
Alec Mouri4049b532021-10-15 20:59:33 -07003005TEST_P(RenderEngineTest, test_tonemapPQMatches) {
Alec Mouri47bcb072023-08-15 02:02:49 +00003006 if (!GetParam()->typeSupported()) {
Alec Mouri5a493722022-01-26 16:43:02 -08003007 GTEST_SKIP();
Alec Mouri4049b532021-10-15 20:59:33 -07003008 }
3009
Alec Mouri4049b532021-10-15 20:59:33 -07003010 initializeRenderEngine();
3011
Alec Mouri5a493722022-01-26 16:43:02 -08003012 tonemap(
3013 static_cast<ui::Dataspace>(HAL_DATASPACE_STANDARD_BT2020 |
3014 HAL_DATASPACE_TRANSFER_ST2084 | HAL_DATASPACE_RANGE_FULL),
3015 [](vec3 color) { return EOTF_PQ(color); },
3016 [](vec3 color, float) {
3017 static constexpr float kMaxPQLuminance = 10000.f;
3018 return color * kMaxPQLuminance;
3019 });
3020}
Alec Mouri4049b532021-10-15 20:59:33 -07003021
Alec Mouri5a493722022-01-26 16:43:02 -08003022TEST_P(RenderEngineTest, test_tonemapHLGMatches) {
Alec Mouri47bcb072023-08-15 02:02:49 +00003023 if (!GetParam()->typeSupported()) {
Alec Mouri5a493722022-01-26 16:43:02 -08003024 GTEST_SKIP();
Alec Mouri4049b532021-10-15 20:59:33 -07003025 }
3026
Alec Mouri5a493722022-01-26 16:43:02 -08003027 initializeRenderEngine();
Alec Mouri4049b532021-10-15 20:59:33 -07003028
Alec Mouri5a493722022-01-26 16:43:02 -08003029 tonemap(
3030 static_cast<ui::Dataspace>(HAL_DATASPACE_STANDARD_BT2020 | HAL_DATASPACE_TRANSFER_HLG |
3031 HAL_DATASPACE_RANGE_FULL),
3032 [](vec3 color) { return EOTF_HLG(color); },
3033 [](vec3 color, float currentLuminaceNits) {
3034 static constexpr float kMaxHLGLuminance = 1000.f;
Alec Mouri7a577452022-03-04 23:41:38 +00003035 return color * kMaxHLGLuminance;
Alec Mouri5a493722022-01-26 16:43:02 -08003036 });
Alec Mouri4049b532021-10-15 20:59:33 -07003037}
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -05003038
3039TEST_P(RenderEngineTest, r8_behaves_as_mask) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003040 if (!GetParam()->typeSupported()) {
3041 GTEST_SKIP();
3042 }
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -05003043 initializeRenderEngine();
3044
3045 const auto r8Buffer = allocateR8Buffer(2, 1);
3046 if (!r8Buffer) {
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003047 GTEST_SKIP() << "Test is only necessary on devices that support r8";
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -05003048 return;
3049 }
3050 {
3051 uint8_t* pixels;
3052 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
3053 reinterpret_cast<void**>(&pixels));
3054 // This will be drawn on top of a green buffer. We'll verify that 255
3055 // results in keeping the original green and 0 results in black.
3056 pixels[0] = 0;
3057 pixels[1] = 255;
3058 r8Buffer->getBuffer()->unlock();
3059 }
3060
3061 const auto rect = Rect(0, 0, 2, 1);
3062 const renderengine::DisplaySettings display{
3063 .physicalDisplay = rect,
3064 .clip = rect,
3065 .outputDataspace = ui::Dataspace::SRGB,
3066 };
3067
3068 const auto greenBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(0, 255, 0, 255));
3069 const renderengine::LayerSettings greenLayer{
3070 .geometry.boundaries = rect.toFloatRect(),
3071 .source =
3072 renderengine::PixelSource{
3073 .buffer =
3074 renderengine::Buffer{
3075 .buffer = greenBuffer,
3076 },
3077 },
3078 .alpha = 1.0f,
3079 };
3080 const renderengine::LayerSettings r8Layer{
3081 .geometry.boundaries = rect.toFloatRect(),
3082 .source =
3083 renderengine::PixelSource{
3084 .buffer =
3085 renderengine::Buffer{
3086 .buffer = r8Buffer,
3087 },
3088 },
3089 .alpha = 1.0f,
3090 };
3091
3092 std::vector<renderengine::LayerSettings> layers{greenLayer, r8Layer};
3093 invokeDraw(display, layers);
3094
3095 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 255);
3096 expectBufferColor(Rect(1, 0, 2, 1), 0, 255, 0, 255);
3097}
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003098
3099TEST_P(RenderEngineTest, r8_respects_color_transform) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003100 if (!GetParam()->typeSupported()) {
3101 GTEST_SKIP();
3102 }
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003103 initializeRenderEngine();
3104
3105 const auto r8Buffer = allocateR8Buffer(2, 1);
3106 if (!r8Buffer) {
3107 GTEST_SKIP() << "Test is only necessary on devices that support r8";
3108 return;
3109 }
3110 {
3111 uint8_t* pixels;
3112 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
3113 reinterpret_cast<void**>(&pixels));
3114 pixels[0] = 0;
3115 pixels[1] = 255;
3116 r8Buffer->getBuffer()->unlock();
3117 }
3118
3119 const auto rect = Rect(0, 0, 2, 1);
3120 const renderengine::DisplaySettings display{
3121 .physicalDisplay = rect,
3122 .clip = rect,
3123 .outputDataspace = ui::Dataspace::SRGB,
3124 // Verify that the R8 layer respects the color transform when
3125 // deviceHandlesColorTransform is false. This transform converts
3126 // pure red to pure green. That will occur when the R8 buffer is
3127 // 255. When the R8 buffer is 0, it will still change to black, as
3128 // with r8_behaves_as_mask.
Alec Mouri9bcd1d12022-04-21 22:16:56 +00003129 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003130 .deviceHandlesColorTransform = false,
3131 };
3132
3133 const auto redBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(255, 0, 0, 255));
3134 const renderengine::LayerSettings redLayer{
3135 .geometry.boundaries = rect.toFloatRect(),
3136 .source =
3137 renderengine::PixelSource{
3138 .buffer =
3139 renderengine::Buffer{
3140 .buffer = redBuffer,
3141 },
3142 },
3143 .alpha = 1.0f,
3144 };
3145 const renderengine::LayerSettings r8Layer{
3146 .geometry.boundaries = rect.toFloatRect(),
3147 .source =
3148 renderengine::PixelSource{
3149 .buffer =
3150 renderengine::Buffer{
3151 .buffer = r8Buffer,
3152 },
3153 },
3154 .alpha = 1.0f,
3155 };
3156
3157 std::vector<renderengine::LayerSettings> layers{redLayer, r8Layer};
3158 invokeDraw(display, layers);
3159
3160 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 255);
3161 expectBufferColor(Rect(1, 0, 2, 1), 0, 255, 0, 255);
3162}
3163
3164TEST_P(RenderEngineTest, r8_respects_color_transform_when_device_handles) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003165 if (!GetParam()->typeSupported()) {
3166 GTEST_SKIP();
3167 }
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003168 initializeRenderEngine();
3169
3170 const auto r8Buffer = allocateR8Buffer(2, 1);
3171 if (!r8Buffer) {
3172 GTEST_SKIP() << "Test is only necessary on devices that support r8";
3173 return;
3174 }
3175 {
3176 uint8_t* pixels;
3177 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
3178 reinterpret_cast<void**>(&pixels));
3179 pixels[0] = 0;
3180 pixels[1] = 255;
3181 r8Buffer->getBuffer()->unlock();
3182 }
3183
3184 const auto rect = Rect(0, 0, 2, 1);
3185 const renderengine::DisplaySettings display{
3186 .physicalDisplay = rect,
3187 .clip = rect,
3188 .outputDataspace = ui::Dataspace::SRGB,
3189 // If deviceHandlesColorTransform is true, pixels where the A8
3190 // buffer is opaque are unaffected. If the colorTransform is
3191 // invertible, pixels where the A8 buffer are transparent have the
3192 // inverse applied to them so that the DPU will convert them back to
3193 // black. Test with an arbitrary, invertible matrix.
3194 .colorTransform = mat4(1, 0, 0, 2,
3195 3, 1, 2, 5,
3196 0, 5, 3, 0,
3197 0, 1, 0, 2),
3198 .deviceHandlesColorTransform = true,
3199 };
3200
3201 const auto redBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(255, 0, 0, 255));
3202 const renderengine::LayerSettings redLayer{
3203 .geometry.boundaries = rect.toFloatRect(),
3204 .source =
3205 renderengine::PixelSource{
3206 .buffer =
3207 renderengine::Buffer{
3208 .buffer = redBuffer,
3209 },
3210 },
3211 .alpha = 1.0f,
3212 };
3213 const renderengine::LayerSettings r8Layer{
3214 .geometry.boundaries = rect.toFloatRect(),
3215 .source =
3216 renderengine::PixelSource{
3217 .buffer =
3218 renderengine::Buffer{
3219 .buffer = r8Buffer,
3220 },
3221 },
3222 .alpha = 1.0f,
3223 };
3224
3225 std::vector<renderengine::LayerSettings> layers{redLayer, r8Layer};
3226 invokeDraw(display, layers);
3227
3228 expectBufferColor(Rect(1, 0, 2, 1), 255, 0, 0, 255); // Still red.
3229 expectBufferColor(Rect(0, 0, 1, 1), 0, 70, 0, 255);
3230}
Leon Scroggins III45be9182022-04-27 10:37:11 -04003231
3232TEST_P(RenderEngineTest, primeShaderCache) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003233 if (!GetParam()->typeSupported()) {
3234 GTEST_SKIP();
3235 }
Leon Scroggins III45be9182022-04-27 10:37:11 -04003236 initializeRenderEngine();
3237
3238 auto fut = mRE->primeCache();
3239 if (fut.valid()) {
3240 fut.wait();
3241 }
3242
Alec Mouri47bcb072023-08-15 02:02:49 +00003243 static constexpr int kMinimumExpectedShadersCompiled = 60;
Leon Scroggins III45be9182022-04-27 10:37:11 -04003244 ASSERT_GT(static_cast<skia::SkiaGLRenderEngine*>(mRE.get())->reportShadersCompiled(),
Alec Mouri47bcb072023-08-15 02:02:49 +00003245 kMinimumExpectedShadersCompiled);
Leon Scroggins III45be9182022-04-27 10:37:11 -04003246}
Derek Sollenbergerd3f60652021-06-11 15:34:36 -04003247} // namespace renderengine
Alec Mouri6e57f682018-09-29 20:45:08 -07003248} // namespace android
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08003249
3250// TODO(b/129481165): remove the #pragma below and fix conversion issues
Marin Shalamanovbed7fd32020-12-21 20:02:20 +01003251#pragma clang diagnostic pop // ignored "-Wconversion -Wextra"