blob: 640c434990c67b537c8ad222dfabf4a57ab53dfa [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;
Leon Scroggins III696bf932024-01-24 15:21:05 -0500109 virtual renderengine::RenderEngine::GraphicsApi graphicsApi() = 0;
Nolan Scobie195631a2024-03-26 12:22:23 -0400110 virtual renderengine::RenderEngine::SkiaBackend skiaBackend() = 0;
Leon Scroggins IIIf3369ed2024-02-16 17:52:42 -0500111 bool apiSupported() { return renderengine::RenderEngine::canSupport(graphicsApi()); }
Leon Scroggins III5ef55002024-01-25 10:51:45 -0500112 std::unique_ptr<renderengine::RenderEngine> createRenderEngine() {
113 renderengine::RenderEngineCreationArgs reCreationArgs =
114 renderengine::RenderEngineCreationArgs::Builder()
115 .setPixelFormat(static_cast<int>(ui::PixelFormat::RGBA_8888))
116 .setImageCacheSize(1)
117 .setEnableProtectedContext(false)
118 .setPrecacheToneMapperShaderOnly(false)
Robin Lee7338bd92024-04-04 14:05:07 +0000119 .setBlurAlgorithm(renderengine::RenderEngine::BlurAlgorithm::KAWASE)
Leon Scroggins III5ef55002024-01-25 10:51:45 -0500120 .setContextPriority(renderengine::RenderEngine::ContextPriority::MEDIUM)
Leon Scroggins III696bf932024-01-24 15:21:05 -0500121 .setThreaded(renderengine::RenderEngine::Threaded::NO)
122 .setGraphicsApi(graphicsApi())
Nolan Scobie195631a2024-03-26 12:22:23 -0400123 .setSkiaBackend(skiaBackend())
Leon Scroggins III5ef55002024-01-25 10:51:45 -0500124 .build();
125 return renderengine::RenderEngine::create(reCreationArgs);
126 }
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800127};
128
Alec Mouri0eab3e82020-12-08 18:10:27 -0800129class SkiaGLESRenderEngineFactory : public RenderEngineFactory {
130public:
Alec Mouric0aae732021-01-12 13:32:18 -0800131 std::string name() override { return "SkiaGLRenderEngineFactory"; }
Alec Mouri0eab3e82020-12-08 18:10:27 -0800132
Leon Scroggins III696bf932024-01-24 15:21:05 -0500133 renderengine::RenderEngine::GraphicsApi graphicsApi() {
134 return renderengine::RenderEngine::GraphicsApi::GL;
Alec Mouric0aae732021-01-12 13:32:18 -0800135 }
Nolan Scobie195631a2024-03-26 12:22:23 -0400136
137 renderengine::RenderEngine::SkiaBackend skiaBackend() override {
138 return renderengine::RenderEngine::SkiaBackend::GANESH;
139 }
140};
141
142class GaneshVkRenderEngineFactory : public RenderEngineFactory {
143public:
144 std::string name() override { return "GaneshVkRenderEngineFactory"; }
145
146 renderengine::RenderEngine::GraphicsApi graphicsApi() override {
147 return renderengine::RenderEngine::GraphicsApi::VK;
148 }
149
150 renderengine::RenderEngine::SkiaBackend skiaBackend() override {
151 return renderengine::RenderEngine::SkiaBackend::GANESH;
152 }
153};
154
155class GraphiteVkRenderEngineFactory : public RenderEngineFactory {
156public:
157 std::string name() override { return "GraphiteVkRenderEngineFactory"; }
158
159 renderengine::RenderEngine::GraphicsApi graphicsApi() override {
160 return renderengine::RenderEngine::GraphicsApi::VK;
161 }
162
163 renderengine::RenderEngine::SkiaBackend skiaBackend() override {
164 return renderengine::RenderEngine::SkiaBackend::GRAPHITE;
165 }
Alec Mouri0eab3e82020-12-08 18:10:27 -0800166};
167
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800168class RenderEngineTest : public ::testing::TestWithParam<std::shared_ptr<RenderEngineFactory>> {
169public:
Alec Mouria90a5702021-04-16 16:36:21 +0000170 std::shared_ptr<renderengine::ExternalTexture> allocateDefaultBuffer() {
171 return std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800172 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -0700173 ExternalTexture>(sp<GraphicBuffer>::
174 make(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT,
175 HAL_PIXEL_FORMAT_RGBA_8888, 1,
176 GRALLOC_USAGE_SW_READ_OFTEN |
177 GRALLOC_USAGE_SW_WRITE_OFTEN |
178 GRALLOC_USAGE_HW_RENDER |
179 GRALLOC_USAGE_HW_TEXTURE,
180 "output"),
Alec Mouria90a5702021-04-16 16:36:21 +0000181 *mRE,
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800182 renderengine::impl::ExternalTexture::Usage::READABLE |
183 renderengine::impl::ExternalTexture::Usage::
184 WRITEABLE);
Alec Mouri6e57f682018-09-29 20:45:08 -0700185 }
186
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800187 // Allocates a 1x1 buffer to fill with a solid color
Alec Mouria90a5702021-04-16 16:36:21 +0000188 std::shared_ptr<renderengine::ExternalTexture> allocateSourceBuffer(uint32_t width,
189 uint32_t height) {
190 return std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800191 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -0700192 ExternalTexture>(sp<GraphicBuffer>::
193 make(width, height, HAL_PIXEL_FORMAT_RGBA_8888, 1,
194 GRALLOC_USAGE_SW_READ_OFTEN |
195 GRALLOC_USAGE_SW_WRITE_OFTEN |
196 GRALLOC_USAGE_HW_TEXTURE,
197 "input"),
Alec Mouria90a5702021-04-16 16:36:21 +0000198 *mRE,
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800199 renderengine::impl::ExternalTexture::Usage::READABLE |
200 renderengine::impl::ExternalTexture::Usage::
201 WRITEABLE);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800202 }
203
Alec Mouricdf6cbc2021-11-01 17:21:15 -0700204 std::shared_ptr<renderengine::ExternalTexture> allocateAndFillSourceBuffer(uint32_t width,
205 uint32_t height,
206 ubyte4 color) {
207 const auto buffer = allocateSourceBuffer(width, height);
208 uint8_t* pixels;
209 buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
210 reinterpret_cast<void**>(&pixels));
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -0500211 for (uint32_t j = 0; j < height; j++) {
212 uint8_t* dst = pixels + (buffer->getBuffer()->getStride() * j * 4);
213 for (uint32_t i = 0; i < width; i++) {
214 dst[0] = color.r;
215 dst[1] = color.g;
216 dst[2] = color.b;
217 dst[3] = color.a;
218 dst += 4;
219 }
220 }
Alec Mouricdf6cbc2021-11-01 17:21:15 -0700221 buffer->getBuffer()->unlock();
222 return buffer;
223 }
224
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -0500225 std::shared_ptr<renderengine::ExternalTexture> allocateR8Buffer(int width, int height) {
Ady Abrahamd11bade2022-08-01 16:18:03 -0700226 const auto kUsageFlags =
227 static_cast<uint64_t>(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
228 GRALLOC_USAGE_HW_TEXTURE);
229 auto buffer =
230 sp<GraphicBuffer>::make(static_cast<uint32_t>(width), static_cast<uint32_t>(height),
231 android::PIXEL_FORMAT_R_8, 1u, kUsageFlags, "r8");
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -0500232 if (buffer->initCheck() != 0) {
233 // Devices are not required to support R8.
234 return nullptr;
235 }
236 return std::make_shared<
237 renderengine::impl::ExternalTexture>(std::move(buffer), *mRE,
238 renderengine::impl::ExternalTexture::Usage::
239 READABLE);
240 }
241
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800242 RenderEngineTest() {
243 const ::testing::TestInfo* const test_info =
244 ::testing::UnitTest::GetInstance()->current_test_info();
245 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800246 }
Alec Mouri1089aed2018-10-25 21:33:57 -0700247
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800248 ~RenderEngineTest() {
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800249 if (WRITE_BUFFER_TO_FILE_ON_FAILURE && ::testing::Test::HasFailure()) {
250 writeBufferToFile("/data/texture_out_");
251 }
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800252 const ::testing::TestInfo* const test_info =
253 ::testing::UnitTest::GetInstance()->current_test_info();
254 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800255 }
256
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800257 void writeBufferToFile(const char* basename) {
258 std::string filename(basename);
259 filename.append(::testing::UnitTest::GetInstance()->current_test_info()->name());
260 filename.append(".ppm");
261 std::ofstream file(filename.c_str(), std::ios::binary);
262 if (!file.is_open()) {
263 ALOGE("Unable to open file: %s", filename.c_str());
264 ALOGE("You may need to do: \"adb shell setenforce 0\" to enable "
265 "surfaceflinger to write debug images");
266 return;
267 }
268
Alec Mouri1089aed2018-10-25 21:33:57 -0700269 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +0000270 mBuffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
271 reinterpret_cast<void**>(&pixels));
Alec Mouri1089aed2018-10-25 21:33:57 -0700272
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800273 file << "P6\n";
Alec Mouria90a5702021-04-16 16:36:21 +0000274 file << mBuffer->getBuffer()->getWidth() << "\n";
275 file << mBuffer->getBuffer()->getHeight() << "\n";
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800276 file << 255 << "\n";
277
Alec Mouria90a5702021-04-16 16:36:21 +0000278 std::vector<uint8_t> outBuffer(mBuffer->getBuffer()->getWidth() *
279 mBuffer->getBuffer()->getHeight() * 3);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800280 auto outPtr = reinterpret_cast<uint8_t*>(outBuffer.data());
281
Alec Mouria90a5702021-04-16 16:36:21 +0000282 for (int32_t j = 0; j < mBuffer->getBuffer()->getHeight(); j++) {
283 const uint8_t* src = pixels + (mBuffer->getBuffer()->getStride() * j) * 4;
284 for (int32_t i = 0; i < mBuffer->getBuffer()->getWidth(); i++) {
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800285 // Only copy R, G and B components
286 outPtr[0] = src[0];
287 outPtr[1] = src[1];
288 outPtr[2] = src[2];
289 outPtr += 3;
290
291 src += 4;
292 }
293 }
294 file.write(reinterpret_cast<char*>(outBuffer.data()), outBuffer.size());
Alec Mouria90a5702021-04-16 16:36:21 +0000295 mBuffer->getBuffer()->unlock();
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800296 }
297
298 void expectBufferColor(const Region& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
299 size_t c;
300 Rect const* rect = region.getArray(&c);
301 for (size_t i = 0; i < c; i++, rect++) {
302 expectBufferColor(*rect, r, g, b, a);
303 }
304 }
305
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -0400306 void expectBufferColor(const Point& point, uint8_t r, uint8_t g, uint8_t b, uint8_t a,
307 uint8_t tolerance = 0) {
308 expectBufferColor(Rect(point.x, point.y, point.x + 1, point.y + 1), r, g, b, a, tolerance);
309 }
310
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800311 void expectBufferColor(const Rect& rect, uint8_t r, uint8_t g, uint8_t b, uint8_t a,
312 uint8_t tolerance = 0) {
Alec Mouri4049b532021-10-15 20:59:33 -0700313 auto generator = [=](Point) { return ubyte4(r, g, b, a); };
314 expectBufferColor(rect, generator, tolerance);
315 }
316
317 using ColorGenerator = std::function<ubyte4(Point location)>;
318
319 void expectBufferColor(const Rect& rect, ColorGenerator generator, uint8_t tolerance = 0) {
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800320 auto colorCompare = [tolerance](const uint8_t* colorA, const uint8_t* colorB) {
321 auto colorBitCompare = [tolerance](uint8_t a, uint8_t b) {
322 uint8_t tmp = a >= b ? a - b : b - a;
323 return tmp <= tolerance;
324 };
325 return std::equal(colorA, colorA + 4, colorB, colorBitCompare);
Alec Mouri1089aed2018-10-25 21:33:57 -0700326 };
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800327
Alec Mouri4049b532021-10-15 20:59:33 -0700328 expectBufferColor(rect, generator, colorCompare);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800329 }
330
Alec Mouri4049b532021-10-15 20:59:33 -0700331 void expectBufferColor(const Rect& region, ColorGenerator generator,
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800332 std::function<bool(const uint8_t* a, const uint8_t* b)> colorCompare) {
333 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +0000334 mBuffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
335 reinterpret_cast<void**>(&pixels));
Alec Mouri1089aed2018-10-25 21:33:57 -0700336 int32_t maxFails = 10;
337 int32_t fails = 0;
338 for (int32_t j = 0; j < region.getHeight(); j++) {
Alec Mouria90a5702021-04-16 16:36:21 +0000339 const uint8_t* src = pixels +
340 (mBuffer->getBuffer()->getStride() * (region.top + j) + region.left) * 4;
Alec Mouri1089aed2018-10-25 21:33:57 -0700341 for (int32_t i = 0; i < region.getWidth(); i++) {
Alec Mouri4049b532021-10-15 20:59:33 -0700342 const auto location = Point(region.left + i, region.top + j);
343 const ubyte4 colors = generator(location);
344 const uint8_t expected[4] = {colors.r, colors.g, colors.b, colors.a};
345 bool colorMatches = colorCompare(src, expected);
346 EXPECT_TRUE(colorMatches)
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -0400347 << GetParam()->name().c_str() << ": "
Alec Mouri4049b532021-10-15 20:59:33 -0700348 << "pixel @ (" << location.x << ", " << location.y << "): "
349 << "expected (" << static_cast<uint32_t>(colors.r) << ", "
350 << static_cast<uint32_t>(colors.g) << ", "
351 << static_cast<uint32_t>(colors.b) << ", "
352 << static_cast<uint32_t>(colors.a) << "), "
Alec Mouri1089aed2018-10-25 21:33:57 -0700353 << "got (" << static_cast<uint32_t>(src[0]) << ", "
354 << static_cast<uint32_t>(src[1]) << ", " << static_cast<uint32_t>(src[2])
355 << ", " << static_cast<uint32_t>(src[3]) << ")";
356 src += 4;
Alec Mouri4049b532021-10-15 20:59:33 -0700357 if (!colorMatches && ++fails >= maxFails) {
Alec Mouri1089aed2018-10-25 21:33:57 -0700358 break;
359 }
360 }
361 if (fails >= maxFails) {
362 break;
363 }
364 }
Alec Mouria90a5702021-04-16 16:36:21 +0000365 mBuffer->getBuffer()->unlock();
Alec Mouri1089aed2018-10-25 21:33:57 -0700366 }
367
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800368 void expectAlpha(const Rect& rect, uint8_t a) {
Alec Mouri4049b532021-10-15 20:59:33 -0700369 auto generator = [=](Point) { return ubyte4(0, 0, 0, a); };
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800370 auto colorCompare = [](const uint8_t* colorA, const uint8_t* colorB) {
371 return colorA[3] == colorB[3];
372 };
Alec Mouri4049b532021-10-15 20:59:33 -0700373 expectBufferColor(rect, generator, colorCompare);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800374 }
375
376 void expectShadowColor(const renderengine::LayerSettings& castingLayer,
Vishnu Naird9e4f462023-10-06 04:05:45 +0000377 const ShadowSettings& shadow, const ubyte4& casterColor,
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800378 const ubyte4& backgroundColor) {
379 const Rect casterRect(castingLayer.geometry.boundaries);
380 Region casterRegion = Region(casterRect);
Vishnu Nair50c0afe2022-07-11 15:04:07 -0700381 const float casterCornerRadius = (castingLayer.geometry.roundedCornersRadius.x +
382 castingLayer.geometry.roundedCornersRadius.y) /
383 2.0;
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800384 if (casterCornerRadius > 0.0f) {
385 // ignore the corners if a corner radius is set
386 Rect cornerRect(casterCornerRadius, casterCornerRadius);
387 casterRegion.subtractSelf(cornerRect.offsetTo(casterRect.left, casterRect.top));
388 casterRegion.subtractSelf(
389 cornerRect.offsetTo(casterRect.right - casterCornerRadius, casterRect.top));
390 casterRegion.subtractSelf(
391 cornerRect.offsetTo(casterRect.left, casterRect.bottom - casterCornerRadius));
392 casterRegion.subtractSelf(cornerRect.offsetTo(casterRect.right - casterCornerRadius,
393 casterRect.bottom - casterCornerRadius));
394 }
395
396 const float shadowInset = shadow.length * -1.0f;
397 const Rect casterWithShadow =
398 Rect(casterRect).inset(shadowInset, shadowInset, shadowInset, shadowInset);
399 const Region shadowRegion = Region(casterWithShadow).subtractSelf(casterRect);
400 const Region backgroundRegion = Region(fullscreenRect()).subtractSelf(casterWithShadow);
401
402 // verify casting layer
403 expectBufferColor(casterRegion, casterColor.r, casterColor.g, casterColor.b, casterColor.a);
404
405 // verify shadows by testing just the alpha since its difficult to validate the shadow color
406 size_t c;
407 Rect const* r = shadowRegion.getArray(&c);
408 for (size_t i = 0; i < c; i++, r++) {
409 expectAlpha(*r, 255);
410 }
411
412 // verify background
413 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
414 backgroundColor.a);
415 }
416
Vishnu Naird9e4f462023-10-06 04:05:45 +0000417 void expectShadowColorWithoutCaster(const FloatRect& casterBounds, const ShadowSettings& shadow,
Alec Mouribd17b3b2020-12-17 11:08:30 -0800418 const ubyte4& backgroundColor) {
419 const float shadowInset = shadow.length * -1.0f;
420 const Rect casterRect(casterBounds);
421 const Rect shadowRect =
422 Rect(casterRect).inset(shadowInset, shadowInset, shadowInset, shadowInset);
423
424 const Region backgroundRegion =
425 Region(fullscreenRect()).subtractSelf(casterRect).subtractSelf(shadowRect);
426
427 expectAlpha(shadowRect, 255);
428 // (0, 0, 0) fill on the bounds of the layer should be ignored.
429 expectBufferColor(casterRect, 255, 255, 255, 255, 254);
430
431 // verify background
432 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
433 backgroundColor.a);
434 }
435
Vishnu Naird9e4f462023-10-06 04:05:45 +0000436 static ShadowSettings getShadowSettings(const vec2& casterPos, float shadowLength,
437 bool casterIsTranslucent) {
438 ShadowSettings shadow;
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800439 shadow.ambientColor = {0.0f, 0.0f, 0.0f, 0.039f};
440 shadow.spotColor = {0.0f, 0.0f, 0.0f, 0.19f};
441 shadow.lightPos = vec3(casterPos.x, casterPos.y, 0);
442 shadow.lightRadius = 0.0f;
443 shadow.length = shadowLength;
444 shadow.casterIsTranslucent = casterIsTranslucent;
445 return shadow;
446 }
447
Alec Mouri1089aed2018-10-25 21:33:57 -0700448 static Rect fullscreenRect() { return Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT); }
449
450 static Rect offsetRect() {
451 return Rect(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_WIDTH,
452 DEFAULT_DISPLAY_HEIGHT);
453 }
454
455 static Rect offsetRectAtZero() {
456 return Rect(DEFAULT_DISPLAY_WIDTH - DEFAULT_DISPLAY_OFFSET,
457 DEFAULT_DISPLAY_HEIGHT - DEFAULT_DISPLAY_OFFSET);
458 }
459
Sally Qi59a9f502021-10-12 18:53:23 +0000460 void invokeDraw(const renderengine::DisplaySettings& settings,
461 const std::vector<renderengine::LayerSettings>& layers) {
Patrick Williams2e9748f2022-08-09 22:48:18 +0000462 ftl::Future<FenceResult> future =
Alec Mourif29700f2023-08-17 21:53:31 +0000463 mRE->drawLayers(settings, layers, mBuffer, base::unique_fd());
Patrick Williams2e9748f2022-08-09 22:48:18 +0000464 ASSERT_TRUE(future.valid());
Sally Qi59a9f502021-10-12 18:53:23 +0000465
Patrick Williams2e9748f2022-08-09 22:48:18 +0000466 auto result = future.get();
467 ASSERT_TRUE(result.ok());
Alec Mouri1089aed2018-10-25 21:33:57 -0700468
Patrick Williams2e9748f2022-08-09 22:48:18 +0000469 auto fence = result.value();
470 fence->waitForever(LOG_TAG);
Alec Mouri1089aed2018-10-25 21:33:57 -0700471 }
472
Alec Mourid43ccab2019-03-13 12:23:45 -0700473 void drawEmptyLayers() {
Alec Mouri6e57f682018-09-29 20:45:08 -0700474 renderengine::DisplaySettings settings;
Sally Qi59a9f502021-10-12 18:53:23 +0000475 std::vector<renderengine::LayerSettings> layers;
Alec Mouric0aae732021-01-12 13:32:18 -0800476 invokeDraw(settings, layers);
Alec Mouri6e57f682018-09-29 20:45:08 -0700477 }
478
Alec Mouri1089aed2018-10-25 21:33:57 -0700479 template <typename SourceVariant>
480 void fillBuffer(half r, half g, half b, half a);
481
482 template <typename SourceVariant>
483 void fillRedBuffer();
484
485 template <typename SourceVariant>
486 void fillGreenBuffer();
487
488 template <typename SourceVariant>
489 void fillBlueBuffer();
490
491 template <typename SourceVariant>
492 void fillRedTransparentBuffer();
493
494 template <typename SourceVariant>
495 void fillRedOffsetBuffer();
496
497 template <typename SourceVariant>
498 void fillBufferPhysicalOffset();
499
500 template <typename SourceVariant>
Alec Mouri5a6d8572020-03-23 23:56:15 -0700501 void fillBufferCheckers(uint32_t rotation);
Alec Mouri1089aed2018-10-25 21:33:57 -0700502
503 template <typename SourceVariant>
504 void fillBufferCheckersRotate0();
505
506 template <typename SourceVariant>
507 void fillBufferCheckersRotate90();
508
509 template <typename SourceVariant>
510 void fillBufferCheckersRotate180();
511
512 template <typename SourceVariant>
513 void fillBufferCheckersRotate270();
514
515 template <typename SourceVariant>
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800516 void fillBufferWithLayerTransform();
517
518 template <typename SourceVariant>
Alec Mouri1089aed2018-10-25 21:33:57 -0700519 void fillBufferLayerTransform();
520
521 template <typename SourceVariant>
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800522 void fillBufferWithColorTransform();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800523
524 template <typename SourceVariant>
Alec Mouri1089aed2018-10-25 21:33:57 -0700525 void fillBufferColorTransform();
526
Alec Mouri7c94edb2018-12-03 21:23:26 -0800527 template <typename SourceVariant>
Sally Qi2019fd22021-11-22 10:19:04 -0800528 void fillBufferWithColorTransformAndSourceDataspace(const ui::Dataspace sourceDataspace);
529
530 template <typename SourceVariant>
531 void fillBufferColorTransformAndSourceDataspace();
532
533 template <typename SourceVariant>
534 void fillBufferWithColorTransformAndOutputDataspace(const ui::Dataspace outputDataspace);
535
536 template <typename SourceVariant>
537 void fillBufferColorTransformAndOutputDataspace();
538
539 template <typename SourceVariant>
KaiChieh Chuangda2845c2020-12-14 16:49:38 +0800540 void fillBufferWithColorTransformZeroLayerAlpha();
541
542 template <typename SourceVariant>
543 void fillBufferColorTransformZeroLayerAlpha();
544
545 template <typename SourceVariant>
Alec Mouri7c94edb2018-12-03 21:23:26 -0800546 void fillRedBufferWithRoundedCorners();
547
548 template <typename SourceVariant>
549 void fillBufferWithRoundedCorners();
550
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000551 template <typename SourceVariant>
Lucas Dupin19c8f0e2019-11-25 17:55:44 -0800552 void fillBufferAndBlurBackground();
553
554 template <typename SourceVariant>
Alec Mourie8489fd2021-04-29 16:08:56 -0700555 void fillSmallLayerAndBlurBackground();
556
557 template <typename SourceVariant>
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000558 void overlayCorners();
559
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800560 void fillRedBufferTextureTransform();
561
562 void fillBufferTextureTransform();
563
564 void fillRedBufferWithPremultiplyAlpha();
565
566 void fillBufferWithPremultiplyAlpha();
567
568 void fillRedBufferWithoutPremultiplyAlpha();
569
570 void fillBufferWithoutPremultiplyAlpha();
571
Alec Mouriac335532018-11-12 15:01:33 -0800572 void fillGreenColorBufferThenClearRegion();
573
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800574 template <typename SourceVariant>
Vishnu Naird9e4f462023-10-06 04:05:45 +0000575 void drawShadow(const renderengine::LayerSettings& castingLayer, const ShadowSettings& shadow,
576 const ubyte4& casterColor, const ubyte4& backgroundColor);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800577
Vishnu Naird9e4f462023-10-06 04:05:45 +0000578 void drawShadowWithoutCaster(const FloatRect& castingBounds, const ShadowSettings& shadow,
Alec Mouribd17b3b2020-12-17 11:08:30 -0800579 const ubyte4& backgroundColor);
580
Alec Mouri5a493722022-01-26 16:43:02 -0800581 // Tonemaps grey values from sourceDataspace -> Display P3 and checks that GPU and CPU
582 // implementations are identical Also implicitly checks that the injected tonemap shader
583 // compiles
584 void tonemap(ui::Dataspace sourceDataspace, std::function<vec3(vec3)> eotf,
585 std::function<vec3(vec3, float)> scaleOotf);
586
Alec Mouric0aae732021-01-12 13:32:18 -0800587 void initializeRenderEngine();
588
589 std::unique_ptr<renderengine::RenderEngine> mRE;
Alec Mouria90a5702021-04-16 16:36:21 +0000590 std::shared_ptr<renderengine::ExternalTexture> mBuffer;
Alec Mouri6e57f682018-09-29 20:45:08 -0700591};
592
Alec Mouric0aae732021-01-12 13:32:18 -0800593void RenderEngineTest::initializeRenderEngine() {
594 const auto& renderEngineFactory = GetParam();
Alec Mouric16974e2022-09-13 17:35:48 +0000595 mRE = renderEngineFactory->createRenderEngine();
Alec Mouria90a5702021-04-16 16:36:21 +0000596 mBuffer = allocateDefaultBuffer();
Alec Mouric0aae732021-01-12 13:32:18 -0800597}
598
Alec Mouri1089aed2018-10-25 21:33:57 -0700599struct ColorSourceVariant {
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800600 static void fillColor(renderengine::LayerSettings& layer, half r, half g, half b,
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800601 RenderEngineTest* /*fixture*/) {
Alec Mouri1089aed2018-10-25 21:33:57 -0700602 layer.source.solidColor = half3(r, g, b);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800603 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700604 }
605};
606
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800607struct RelaxOpaqueBufferVariant {
608 static void setOpaqueBit(renderengine::LayerSettings& layer) {
609 layer.source.buffer.isOpaque = false;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800610 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800611 }
612
613 static uint8_t getAlphaChannel() { return 255; }
614};
615
616struct ForceOpaqueBufferVariant {
617 static void setOpaqueBit(renderengine::LayerSettings& layer) {
618 layer.source.buffer.isOpaque = true;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800619 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800620 }
621
622 static uint8_t getAlphaChannel() {
623 // The isOpaque bit will override the alpha channel, so this should be
624 // arbitrary.
Alec Mouric0aae732021-01-12 13:32:18 -0800625 return 50;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800626 }
627};
628
629template <typename OpaquenessVariant>
630struct BufferSourceVariant {
631 static void fillColor(renderengine::LayerSettings& layer, half r, half g, half b,
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800632 RenderEngineTest* fixture) {
Alec Mouria90a5702021-04-16 16:36:21 +0000633 const auto buf = fixture->allocateSourceBuffer(1, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800634
635 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +0000636 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
637 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800638
Alec Mouria90a5702021-04-16 16:36:21 +0000639 for (int32_t j = 0; j < buf->getBuffer()->getHeight(); j++) {
640 uint8_t* iter = pixels + (buf->getBuffer()->getStride() * j) * 4;
641 for (int32_t i = 0; i < buf->getBuffer()->getWidth(); i++) {
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800642 iter[0] = uint8_t(r * 255);
643 iter[1] = uint8_t(g * 255);
644 iter[2] = uint8_t(b * 255);
645 iter[3] = OpaquenessVariant::getAlphaChannel();
646 iter += 4;
647 }
648 }
649
Alec Mouria90a5702021-04-16 16:36:21 +0000650 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800651
652 layer.source.buffer.buffer = buf;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800653 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800654 OpaquenessVariant::setOpaqueBit(layer);
655 }
656};
657
Alec Mouri1089aed2018-10-25 21:33:57 -0700658template <typename SourceVariant>
659void RenderEngineTest::fillBuffer(half r, half g, half b, half a) {
660 renderengine::DisplaySettings settings;
661 settings.physicalDisplay = fullscreenRect();
662 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800663 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700664
Sally Qi59a9f502021-10-12 18:53:23 +0000665 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700666
667 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800668 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700669 layer.geometry.boundaries = fullscreenRect().toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800670 SourceVariant::fillColor(layer, r, g, b, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700671 layer.alpha = a;
672
Sally Qi59a9f502021-10-12 18:53:23 +0000673 layers.push_back(layer);
Alec Mouri1089aed2018-10-25 21:33:57 -0700674
Alec Mouric0aae732021-01-12 13:32:18 -0800675 invokeDraw(settings, layers);
Alec Mouri1089aed2018-10-25 21:33:57 -0700676}
677
678template <typename SourceVariant>
679void RenderEngineTest::fillRedBuffer() {
680 fillBuffer<SourceVariant>(1.0f, 0.0f, 0.0f, 1.0f);
681 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
682}
683
684template <typename SourceVariant>
685void RenderEngineTest::fillGreenBuffer() {
686 fillBuffer<SourceVariant>(0.0f, 1.0f, 0.0f, 1.0f);
687 expectBufferColor(fullscreenRect(), 0, 255, 0, 255);
688}
689
690template <typename SourceVariant>
691void RenderEngineTest::fillBlueBuffer() {
692 fillBuffer<SourceVariant>(0.0f, 0.0f, 1.0f, 1.0f);
693 expectBufferColor(fullscreenRect(), 0, 0, 255, 255);
694}
695
696template <typename SourceVariant>
697void RenderEngineTest::fillRedTransparentBuffer() {
698 fillBuffer<SourceVariant>(1.0f, 0.0f, 0.0f, .2f);
699 expectBufferColor(fullscreenRect(), 51, 0, 0, 51);
700}
701
702template <typename SourceVariant>
703void RenderEngineTest::fillRedOffsetBuffer() {
704 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800705 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700706 settings.physicalDisplay = offsetRect();
707 settings.clip = offsetRectAtZero();
708
Sally Qi59a9f502021-10-12 18:53:23 +0000709 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700710
711 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800712 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700713 layer.geometry.boundaries = offsetRectAtZero().toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800714 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700715 layer.alpha = 1.0f;
716
Sally Qi59a9f502021-10-12 18:53:23 +0000717 layers.push_back(layer);
Alec Mouric0aae732021-01-12 13:32:18 -0800718 invokeDraw(settings, layers);
Alec Mouri1089aed2018-10-25 21:33:57 -0700719}
720
721template <typename SourceVariant>
722void RenderEngineTest::fillBufferPhysicalOffset() {
723 fillRedOffsetBuffer<SourceVariant>();
724
725 expectBufferColor(Rect(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_WIDTH,
726 DEFAULT_DISPLAY_HEIGHT),
727 255, 0, 0, 255);
728 Rect offsetRegionLeft(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_HEIGHT);
729 Rect offsetRegionTop(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_OFFSET);
730
731 expectBufferColor(offsetRegionLeft, 0, 0, 0, 0);
732 expectBufferColor(offsetRegionTop, 0, 0, 0, 0);
733}
734
735template <typename SourceVariant>
Alec Mouri5a6d8572020-03-23 23:56:15 -0700736void RenderEngineTest::fillBufferCheckers(uint32_t orientationFlag) {
Alec Mouri1089aed2018-10-25 21:33:57 -0700737 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800738 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700739 settings.physicalDisplay = fullscreenRect();
740 // Here logical space is 2x2
741 settings.clip = Rect(2, 2);
Alec Mouri5a6d8572020-03-23 23:56:15 -0700742 settings.orientation = orientationFlag;
Alec Mouri1089aed2018-10-25 21:33:57 -0700743
Sally Qi59a9f502021-10-12 18:53:23 +0000744 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700745
746 renderengine::LayerSettings layerOne;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800747 layerOne.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700748 Rect rectOne(0, 0, 1, 1);
749 layerOne.geometry.boundaries = rectOne.toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800750 SourceVariant::fillColor(layerOne, 1.0f, 0.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700751 layerOne.alpha = 1.0f;
752
753 renderengine::LayerSettings layerTwo;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800754 layerTwo.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700755 Rect rectTwo(0, 1, 1, 2);
756 layerTwo.geometry.boundaries = rectTwo.toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800757 SourceVariant::fillColor(layerTwo, 0.0f, 1.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700758 layerTwo.alpha = 1.0f;
759
760 renderengine::LayerSettings layerThree;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800761 layerThree.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700762 Rect rectThree(1, 0, 2, 1);
763 layerThree.geometry.boundaries = rectThree.toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800764 SourceVariant::fillColor(layerThree, 0.0f, 0.0f, 1.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700765 layerThree.alpha = 1.0f;
766
Sally Qi59a9f502021-10-12 18:53:23 +0000767 layers.push_back(layerOne);
768 layers.push_back(layerTwo);
769 layers.push_back(layerThree);
Alec Mouri1089aed2018-10-25 21:33:57 -0700770
Alec Mouric0aae732021-01-12 13:32:18 -0800771 invokeDraw(settings, layers);
Alec Mouri1089aed2018-10-25 21:33:57 -0700772}
773
774template <typename SourceVariant>
775void RenderEngineTest::fillBufferCheckersRotate0() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700776 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_0);
Alec Mouri1089aed2018-10-25 21:33:57 -0700777 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0,
778 255);
779 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
780 DEFAULT_DISPLAY_HEIGHT / 2),
781 0, 0, 255, 255);
782 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
783 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
784 0, 0, 0, 0);
785 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
786 DEFAULT_DISPLAY_HEIGHT),
787 0, 255, 0, 255);
788}
789
790template <typename SourceVariant>
791void RenderEngineTest::fillBufferCheckersRotate90() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700792 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_90);
Alec Mouri1089aed2018-10-25 21:33:57 -0700793 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 255, 0,
794 255);
795 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
796 DEFAULT_DISPLAY_HEIGHT / 2),
797 255, 0, 0, 255);
798 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
799 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
800 0, 0, 255, 255);
801 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
802 DEFAULT_DISPLAY_HEIGHT),
803 0, 0, 0, 0);
804}
805
806template <typename SourceVariant>
807void RenderEngineTest::fillBufferCheckersRotate180() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700808 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_180);
Alec Mouri1089aed2018-10-25 21:33:57 -0700809 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 0,
810 0);
811 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
812 DEFAULT_DISPLAY_HEIGHT / 2),
813 0, 255, 0, 255);
814 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
815 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
816 255, 0, 0, 255);
817 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
818 DEFAULT_DISPLAY_HEIGHT),
819 0, 0, 255, 255);
820}
821
822template <typename SourceVariant>
823void RenderEngineTest::fillBufferCheckersRotate270() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700824 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_270);
Alec Mouri1089aed2018-10-25 21:33:57 -0700825 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 255,
826 255);
827 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
828 DEFAULT_DISPLAY_HEIGHT / 2),
829 0, 0, 0, 0);
830 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
831 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
832 0, 255, 0, 255);
833 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
834 DEFAULT_DISPLAY_HEIGHT),
835 255, 0, 0, 255);
836}
837
838template <typename SourceVariant>
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800839void RenderEngineTest::fillBufferWithLayerTransform() {
Alec Mouri1089aed2018-10-25 21:33:57 -0700840 renderengine::DisplaySettings settings;
841 settings.physicalDisplay = fullscreenRect();
842 // Here logical space is 2x2
843 settings.clip = Rect(2, 2);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800844 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700845
Sally Qi59a9f502021-10-12 18:53:23 +0000846 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700847
848 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800849 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700850 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
851 // Translate one pixel diagonally
852 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 -0800853 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700854 layer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
855 layer.alpha = 1.0f;
856
Sally Qi59a9f502021-10-12 18:53:23 +0000857 layers.push_back(layer);
Alec Mouri1089aed2018-10-25 21:33:57 -0700858
Alec Mouric0aae732021-01-12 13:32:18 -0800859 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800860}
Alec Mouri1089aed2018-10-25 21:33:57 -0700861
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800862template <typename SourceVariant>
863void RenderEngineTest::fillBufferLayerTransform() {
864 fillBufferWithLayerTransform<SourceVariant>();
Alec Mouri1089aed2018-10-25 21:33:57 -0700865 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 0, 0);
866 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
867 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
868 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
869 255, 0, 0, 255);
870}
871
872template <typename SourceVariant>
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800873void RenderEngineTest::fillBufferWithColorTransform() {
Alec Mouri1089aed2018-10-25 21:33:57 -0700874 renderengine::DisplaySettings settings;
875 settings.physicalDisplay = fullscreenRect();
876 settings.clip = Rect(1, 1);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800877 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700878
Sally Qi59a9f502021-10-12 18:53:23 +0000879 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700880
881 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800882 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700883 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800884 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700885 layer.alpha = 1.0f;
886
887 // construct a fake color matrix
888 // annihilate green and blue channels
KaiChieh Chuang436fc192020-09-07 13:48:42 +0800889 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
Alec Mouri1089aed2018-10-25 21:33:57 -0700890 // set red channel to red + green
891 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
892
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800893 layer.alpha = 1.0f;
894 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
895
Sally Qi59a9f502021-10-12 18:53:23 +0000896 layers.push_back(layer);
Alec Mouri1089aed2018-10-25 21:33:57 -0700897
Alec Mouric0aae732021-01-12 13:32:18 -0800898 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800899}
Alec Mouri1089aed2018-10-25 21:33:57 -0700900
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800901template <typename SourceVariant>
Sally Qi2019fd22021-11-22 10:19:04 -0800902void RenderEngineTest::fillBufferWithColorTransformAndSourceDataspace(
903 const ui::Dataspace sourceDataspace) {
904 renderengine::DisplaySettings settings;
905 settings.physicalDisplay = fullscreenRect();
906 settings.clip = Rect(1, 1);
907 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
908
909 std::vector<renderengine::LayerSettings> layers;
910
911 renderengine::LayerSettings layer;
Sally Qi2019fd22021-11-22 10:19:04 -0800912 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
913 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
Alec Mouric16974e2022-09-13 17:35:48 +0000914 layer.sourceDataspace = sourceDataspace;
Sally Qi2019fd22021-11-22 10:19:04 -0800915 layer.alpha = 1.0f;
916
917 // construct a fake color matrix
918 // annihilate green and blue channels
919 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
920 // set red channel to red + green
921 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
922
923 layer.alpha = 1.0f;
924 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
925
926 layers.push_back(layer);
927
928 invokeDraw(settings, layers);
929}
930
931template <typename SourceVariant>
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800932void RenderEngineTest::fillBufferColorTransform() {
933 fillBufferWithColorTransform<SourceVariant>();
KaiChieh Chuang436fc192020-09-07 13:48:42 +0800934 expectBufferColor(fullscreenRect(), 172, 0, 0, 255, 1);
935}
936
937template <typename SourceVariant>
Sally Qi2019fd22021-11-22 10:19:04 -0800938void RenderEngineTest::fillBufferColorTransformAndSourceDataspace() {
939 unordered_map<ui::Dataspace, ubyte4> dataspaceToColorMap;
Alec Mouric16974e2022-09-13 17:35:48 +0000940 dataspaceToColorMap[ui::Dataspace::V0_BT709] = {77, 0, 0, 255};
941 dataspaceToColorMap[ui::Dataspace::BT2020] = {101, 0, 0, 255};
942 dataspaceToColorMap[ui::Dataspace::ADOBE_RGB] = {75, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -0800943 ui::Dataspace customizedDataspace = static_cast<ui::Dataspace>(
944 ui::Dataspace::STANDARD_BT709 | ui::Dataspace::TRANSFER_GAMMA2_2 |
945 ui::Dataspace::RANGE_FULL);
Alec Mouric16974e2022-09-13 17:35:48 +0000946 dataspaceToColorMap[customizedDataspace] = {61, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -0800947 for (const auto& [sourceDataspace, color] : dataspaceToColorMap) {
948 fillBufferWithColorTransformAndSourceDataspace<SourceVariant>(sourceDataspace);
949 expectBufferColor(fullscreenRect(), color.r, color.g, color.b, color.a, 1);
950 }
951}
952
953template <typename SourceVariant>
954void RenderEngineTest::fillBufferWithColorTransformAndOutputDataspace(
955 const ui::Dataspace outputDataspace) {
956 renderengine::DisplaySettings settings;
957 settings.physicalDisplay = fullscreenRect();
958 settings.clip = Rect(1, 1);
959 settings.outputDataspace = outputDataspace;
960
961 std::vector<renderengine::LayerSettings> layers;
962
963 renderengine::LayerSettings layer;
964 layer.sourceDataspace = ui::Dataspace::V0_SCRGB_LINEAR;
965 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
966 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
967 layer.alpha = 1.0f;
968
969 // construct a fake color matrix
970 // annihilate green and blue channels
971 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
972 // set red channel to red + green
973 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
974
975 layer.alpha = 1.0f;
976 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
977
978 layers.push_back(layer);
979
980 invokeDraw(settings, layers);
981}
982
983template <typename SourceVariant>
984void RenderEngineTest::fillBufferColorTransformAndOutputDataspace() {
985 unordered_map<ui::Dataspace, ubyte4> dataspaceToColorMap;
Alec Mouric16974e2022-09-13 17:35:48 +0000986 dataspaceToColorMap[ui::Dataspace::V0_BT709] = {198, 0, 0, 255};
987 dataspaceToColorMap[ui::Dataspace::BT2020] = {187, 0, 0, 255};
988 dataspaceToColorMap[ui::Dataspace::ADOBE_RGB] = {192, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -0800989 ui::Dataspace customizedDataspace = static_cast<ui::Dataspace>(
990 ui::Dataspace::STANDARD_BT709 | ui::Dataspace::TRANSFER_GAMMA2_6 |
991 ui::Dataspace::RANGE_FULL);
Alec Mouric16974e2022-09-13 17:35:48 +0000992 dataspaceToColorMap[customizedDataspace] = {205, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -0800993 for (const auto& [outputDataspace, color] : dataspaceToColorMap) {
994 fillBufferWithColorTransformAndOutputDataspace<SourceVariant>(outputDataspace);
995 expectBufferColor(fullscreenRect(), color.r, color.g, color.b, color.a, 1);
996 }
997}
998
999template <typename SourceVariant>
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001000void RenderEngineTest::fillBufferWithColorTransformZeroLayerAlpha() {
1001 renderengine::DisplaySettings settings;
1002 settings.physicalDisplay = fullscreenRect();
1003 settings.clip = Rect(1, 1);
1004
Sally Qi59a9f502021-10-12 18:53:23 +00001005 std::vector<renderengine::LayerSettings> layers;
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001006
1007 renderengine::LayerSettings layer;
1008 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1009 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
1010 layer.alpha = 0;
1011
1012 // construct a fake color matrix
1013 // simple inverse color
1014 settings.colorTransform = mat4(-1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 1, 1, 1, 1);
1015
1016 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1017
Sally Qi59a9f502021-10-12 18:53:23 +00001018 layers.push_back(layer);
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001019
Alec Mouric0aae732021-01-12 13:32:18 -08001020 invokeDraw(settings, layers);
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001021}
1022
1023template <typename SourceVariant>
1024void RenderEngineTest::fillBufferColorTransformZeroLayerAlpha() {
1025 fillBufferWithColorTransformZeroLayerAlpha<SourceVariant>();
1026 expectBufferColor(fullscreenRect(), 0, 0, 0, 0);
1027}
1028
1029template <typename SourceVariant>
Alec Mouri7c94edb2018-12-03 21:23:26 -08001030void RenderEngineTest::fillRedBufferWithRoundedCorners() {
1031 renderengine::DisplaySettings settings;
1032 settings.physicalDisplay = fullscreenRect();
1033 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001034 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri7c94edb2018-12-03 21:23:26 -08001035
Sally Qi59a9f502021-10-12 18:53:23 +00001036 std::vector<renderengine::LayerSettings> layers;
Alec Mouri7c94edb2018-12-03 21:23:26 -08001037
1038 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001039 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri7c94edb2018-12-03 21:23:26 -08001040 layer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07001041 layer.geometry.roundedCornersRadius = {5.0f, 5.0f};
Alec Mouri7c94edb2018-12-03 21:23:26 -08001042 layer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
1043 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
1044 layer.alpha = 1.0f;
1045
Sally Qi59a9f502021-10-12 18:53:23 +00001046 layers.push_back(layer);
Alec Mouri7c94edb2018-12-03 21:23:26 -08001047
Alec Mouric0aae732021-01-12 13:32:18 -08001048 invokeDraw(settings, layers);
Alec Mouri7c94edb2018-12-03 21:23:26 -08001049}
1050
1051template <typename SourceVariant>
1052void RenderEngineTest::fillBufferWithRoundedCorners() {
1053 fillRedBufferWithRoundedCorners<SourceVariant>();
1054 // Corners should be ignored...
1055 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 0);
1056 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, 0, DEFAULT_DISPLAY_WIDTH, 1), 0, 0, 0, 0);
1057 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT - 1, 1, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
1058 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1,
1059 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1060 0, 0, 0, 0);
1061 // ...And the non-rounded portion should be red.
1062 // Other pixels may be anti-aliased, so let's not check those.
1063 expectBufferColor(Rect(5, 5, DEFAULT_DISPLAY_WIDTH - 5, DEFAULT_DISPLAY_HEIGHT - 5), 255, 0, 0,
1064 255);
1065}
1066
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001067template <typename SourceVariant>
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001068void RenderEngineTest::fillBufferAndBlurBackground() {
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001069 auto blurRadius = 50;
1070 auto center = DEFAULT_DISPLAY_WIDTH / 2;
1071
1072 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001073 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001074 settings.physicalDisplay = fullscreenRect();
1075 settings.clip = fullscreenRect();
1076
Sally Qi59a9f502021-10-12 18:53:23 +00001077 std::vector<renderengine::LayerSettings> layers;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001078
1079 renderengine::LayerSettings backgroundLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001080 backgroundLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001081 backgroundLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1082 SourceVariant::fillColor(backgroundLayer, 0.0f, 1.0f, 0.0f, this);
1083 backgroundLayer.alpha = 1.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001084 layers.emplace_back(backgroundLayer);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001085
1086 renderengine::LayerSettings leftLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001087 leftLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001088 leftLayer.geometry.boundaries =
1089 Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT).toFloatRect();
1090 SourceVariant::fillColor(leftLayer, 1.0f, 0.0f, 0.0f, this);
1091 leftLayer.alpha = 1.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001092 layers.emplace_back(leftLayer);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001093
1094 renderengine::LayerSettings blurLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001095 blurLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001096 blurLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1097 blurLayer.backgroundBlurRadius = blurRadius;
Derek Sollenbergerecb21462021-01-29 16:53:49 -05001098 SourceVariant::fillColor(blurLayer, 0.0f, 0.0f, 1.0f, this);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001099 blurLayer.alpha = 0;
Sally Qi59a9f502021-10-12 18:53:23 +00001100 layers.emplace_back(blurLayer);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001101
Alec Mouric0aae732021-01-12 13:32:18 -08001102 invokeDraw(settings, layers);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001103
Derek Sollenbergerecb21462021-01-29 16:53:49 -05001104 // solid color
1105 expectBufferColor(Rect(0, 0, 1, 1), 255, 0, 0, 255, 0 /* tolerance */);
1106
Derek Sollenbergerb3998372021-02-16 15:16:56 -05001107 if (mRE->supportsBackgroundBlur()) {
1108 // blurred color (downsampling should result in the center color being close to 128)
1109 expectBufferColor(Rect(center - 1, center - 5, center + 1, center + 5), 128, 128, 0, 255,
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001110 50 /* tolerance */);
Derek Sollenbergerb3998372021-02-16 15:16:56 -05001111 }
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001112}
1113
1114template <typename SourceVariant>
Alec Mourie8489fd2021-04-29 16:08:56 -07001115void RenderEngineTest::fillSmallLayerAndBlurBackground() {
1116 auto blurRadius = 50;
1117 renderengine::DisplaySettings settings;
1118 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1119 settings.physicalDisplay = fullscreenRect();
1120 settings.clip = fullscreenRect();
1121
Sally Qi59a9f502021-10-12 18:53:23 +00001122 std::vector<renderengine::LayerSettings> layers;
Alec Mourie8489fd2021-04-29 16:08:56 -07001123
1124 renderengine::LayerSettings backgroundLayer;
1125 backgroundLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1126 backgroundLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1127 SourceVariant::fillColor(backgroundLayer, 1.0f, 0.0f, 0.0f, this);
1128 backgroundLayer.alpha = 1.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001129 layers.push_back(backgroundLayer);
Alec Mourie8489fd2021-04-29 16:08:56 -07001130
1131 renderengine::LayerSettings blurLayer;
1132 blurLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1133 blurLayer.geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f);
1134 blurLayer.backgroundBlurRadius = blurRadius;
1135 SourceVariant::fillColor(blurLayer, 0.0f, 0.0f, 1.0f, this);
1136 blurLayer.alpha = 0;
Sally Qi59a9f502021-10-12 18:53:23 +00001137 layers.push_back(blurLayer);
Alec Mourie8489fd2021-04-29 16:08:56 -07001138
1139 invokeDraw(settings, layers);
1140
1141 // Give a generous tolerance - the blur rectangle is very small and this test is
1142 // mainly concerned with ensuring that there's no device failure.
1143 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT), 255, 0, 0, 255,
1144 40 /* tolerance */);
1145}
1146
1147template <typename SourceVariant>
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001148void RenderEngineTest::overlayCorners() {
1149 renderengine::DisplaySettings settings;
1150 settings.physicalDisplay = fullscreenRect();
1151 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001152 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001153
Sally Qi59a9f502021-10-12 18:53:23 +00001154 std::vector<renderengine::LayerSettings> layersFirst;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001155
1156 renderengine::LayerSettings layerOne;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001157 layerOne.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001158 layerOne.geometry.boundaries =
1159 FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH / 3.0, DEFAULT_DISPLAY_HEIGHT / 3.0);
1160 SourceVariant::fillColor(layerOne, 1.0f, 0.0f, 0.0f, this);
1161 layerOne.alpha = 0.2;
1162
Sally Qi59a9f502021-10-12 18:53:23 +00001163 layersFirst.push_back(layerOne);
Alec Mouric0aae732021-01-12 13:32:18 -08001164 invokeDraw(settings, layersFirst);
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001165 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3), 51, 0, 0, 51);
1166 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3 + 1, DEFAULT_DISPLAY_HEIGHT / 3 + 1,
1167 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1168 0, 0, 0, 0);
1169
Sally Qi59a9f502021-10-12 18:53:23 +00001170 std::vector<renderengine::LayerSettings> layersSecond;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001171 renderengine::LayerSettings layerTwo;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001172 layerTwo.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001173 layerTwo.geometry.boundaries =
1174 FloatRect(DEFAULT_DISPLAY_WIDTH / 3.0, DEFAULT_DISPLAY_HEIGHT / 3.0,
1175 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT);
1176 SourceVariant::fillColor(layerTwo, 0.0f, 1.0f, 0.0f, this);
1177 layerTwo.alpha = 1.0f;
1178
Sally Qi59a9f502021-10-12 18:53:23 +00001179 layersSecond.push_back(layerTwo);
Alec Mouric0aae732021-01-12 13:32:18 -08001180 invokeDraw(settings, layersSecond);
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001181
1182 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3), 0, 0, 0, 0);
1183 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3 + 1, DEFAULT_DISPLAY_HEIGHT / 3 + 1,
1184 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1185 0, 255, 0, 255);
1186}
1187
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001188void RenderEngineTest::fillRedBufferTextureTransform() {
1189 renderengine::DisplaySettings settings;
1190 settings.physicalDisplay = fullscreenRect();
1191 settings.clip = Rect(1, 1);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001192 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001193
Sally Qi59a9f502021-10-12 18:53:23 +00001194 std::vector<renderengine::LayerSettings> layers;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001195
1196 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001197 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001198 // Here will allocate a checker board texture, but transform texture
1199 // coordinates so that only the upper left is applied.
Alec Mouria90a5702021-04-16 16:36:21 +00001200 const auto buf = allocateSourceBuffer(2, 2);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001201
1202 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00001203 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1204 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001205 // Red top left, Green top right, Blue bottom left, Black bottom right
1206 pixels[0] = 255;
1207 pixels[1] = 0;
1208 pixels[2] = 0;
1209 pixels[3] = 255;
1210 pixels[4] = 0;
1211 pixels[5] = 255;
1212 pixels[6] = 0;
1213 pixels[7] = 255;
1214 pixels[8] = 0;
1215 pixels[9] = 0;
1216 pixels[10] = 255;
1217 pixels[11] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00001218 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001219
1220 layer.source.buffer.buffer = buf;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001221 // Transform coordinates to only be inside the red quadrant.
Alec Mouri4049b532021-10-15 20:59:33 -07001222 layer.source.buffer.textureTransform = mat4::scale(vec4(0.2f, 0.2f, 1.f, 1.f));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001223 layer.alpha = 1.0f;
1224 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1225
Sally Qi59a9f502021-10-12 18:53:23 +00001226 layers.push_back(layer);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001227
Alec Mouric0aae732021-01-12 13:32:18 -08001228 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001229}
1230
1231void RenderEngineTest::fillBufferTextureTransform() {
1232 fillRedBufferTextureTransform();
1233 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
1234}
1235
1236void RenderEngineTest::fillRedBufferWithPremultiplyAlpha() {
1237 renderengine::DisplaySettings settings;
1238 settings.physicalDisplay = fullscreenRect();
1239 // Here logical space is 1x1
1240 settings.clip = Rect(1, 1);
1241
Sally Qi59a9f502021-10-12 18:53:23 +00001242 std::vector<renderengine::LayerSettings> layers;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001243
1244 renderengine::LayerSettings layer;
Alec Mouria90a5702021-04-16 16:36:21 +00001245 const auto buf = allocateSourceBuffer(1, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001246
1247 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00001248 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1249 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001250 pixels[0] = 255;
1251 pixels[1] = 0;
1252 pixels[2] = 0;
1253 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00001254 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001255
1256 layer.source.buffer.buffer = buf;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001257 layer.source.buffer.usePremultipliedAlpha = true;
1258 layer.alpha = 0.5f;
1259 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1260
Sally Qi59a9f502021-10-12 18:53:23 +00001261 layers.push_back(layer);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001262
Alec Mouric0aae732021-01-12 13:32:18 -08001263 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001264}
1265
1266void RenderEngineTest::fillBufferWithPremultiplyAlpha() {
1267 fillRedBufferWithPremultiplyAlpha();
Nolan Scobie01b93b12024-04-03 21:27:34 +00001268 // Different backends and GPUs may round 255 * 0.5 = 127.5 differently, but
1269 // either 127 or 128 are acceptable. Checking both 127 and 128 with a
1270 // tolerance of 1 allows either 127 or 128 to pass, while preventing 126 or
1271 // 129 from erroneously passing.
1272 expectBufferColor(fullscreenRect(), 127, 0, 0, 127, 1);
1273 expectBufferColor(fullscreenRect(), 128, 0, 0, 128, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001274}
1275
1276void RenderEngineTest::fillRedBufferWithoutPremultiplyAlpha() {
1277 renderengine::DisplaySettings settings;
1278 settings.physicalDisplay = fullscreenRect();
1279 // Here logical space is 1x1
1280 settings.clip = Rect(1, 1);
1281
Sally Qi59a9f502021-10-12 18:53:23 +00001282 std::vector<renderengine::LayerSettings> layers;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001283
1284 renderengine::LayerSettings layer;
Alec Mouria90a5702021-04-16 16:36:21 +00001285 const auto buf = allocateSourceBuffer(1, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001286
1287 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00001288 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1289 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001290 pixels[0] = 255;
1291 pixels[1] = 0;
1292 pixels[2] = 0;
1293 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00001294 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001295
1296 layer.source.buffer.buffer = buf;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001297 layer.source.buffer.usePremultipliedAlpha = false;
1298 layer.alpha = 0.5f;
1299 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1300
Sally Qi59a9f502021-10-12 18:53:23 +00001301 layers.push_back(layer);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001302
Alec Mouric0aae732021-01-12 13:32:18 -08001303 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001304}
1305
1306void RenderEngineTest::fillBufferWithoutPremultiplyAlpha() {
1307 fillRedBufferWithoutPremultiplyAlpha();
wukui16f3c0bb2020-08-05 20:35:29 +08001308 expectBufferColor(fullscreenRect(), 128, 0, 0, 128, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001309}
1310
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001311template <typename SourceVariant>
1312void RenderEngineTest::drawShadow(const renderengine::LayerSettings& castingLayer,
Vishnu Naird9e4f462023-10-06 04:05:45 +00001313 const ShadowSettings& shadow, const ubyte4& casterColor,
1314 const ubyte4& backgroundColor) {
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001315 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001316 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001317 settings.physicalDisplay = fullscreenRect();
1318 settings.clip = fullscreenRect();
1319
Sally Qi59a9f502021-10-12 18:53:23 +00001320 std::vector<renderengine::LayerSettings> layers;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001321
1322 // add background layer
1323 renderengine::LayerSettings bgLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001324 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001325 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1326 ColorSourceVariant::fillColor(bgLayer, backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1327 backgroundColor.b / 255.0f, this);
1328 bgLayer.alpha = backgroundColor.a / 255.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001329 layers.push_back(bgLayer);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001330
1331 // add shadow layer
1332 renderengine::LayerSettings shadowLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001333 shadowLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001334 shadowLayer.geometry.boundaries = castingLayer.geometry.boundaries;
1335 shadowLayer.alpha = castingLayer.alpha;
1336 shadowLayer.shadow = shadow;
Sally Qi59a9f502021-10-12 18:53:23 +00001337 layers.push_back(shadowLayer);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001338
1339 // add layer casting the shadow
1340 renderengine::LayerSettings layer = castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001341 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001342 SourceVariant::fillColor(layer, casterColor.r / 255.0f, casterColor.g / 255.0f,
1343 casterColor.b / 255.0f, this);
Sally Qi59a9f502021-10-12 18:53:23 +00001344 layers.push_back(layer);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001345
Alec Mouric0aae732021-01-12 13:32:18 -08001346 invokeDraw(settings, layers);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001347}
1348
Alec Mouribd17b3b2020-12-17 11:08:30 -08001349void RenderEngineTest::drawShadowWithoutCaster(const FloatRect& castingBounds,
Vishnu Naird9e4f462023-10-06 04:05:45 +00001350 const ShadowSettings& shadow,
Alec Mouribd17b3b2020-12-17 11:08:30 -08001351 const ubyte4& backgroundColor) {
1352 renderengine::DisplaySettings settings;
1353 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1354 settings.physicalDisplay = fullscreenRect();
1355 settings.clip = fullscreenRect();
1356
Sally Qi59a9f502021-10-12 18:53:23 +00001357 std::vector<renderengine::LayerSettings> layers;
Alec Mouribd17b3b2020-12-17 11:08:30 -08001358
1359 // add background layer
1360 renderengine::LayerSettings bgLayer;
1361 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1362 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1363 ColorSourceVariant::fillColor(bgLayer, backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1364 backgroundColor.b / 255.0f, this);
1365 bgLayer.alpha = backgroundColor.a / 255.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001366 layers.push_back(bgLayer);
Alec Mouribd17b3b2020-12-17 11:08:30 -08001367
1368 // add shadow layer
1369 renderengine::LayerSettings shadowLayer;
1370 shadowLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1371 shadowLayer.geometry.boundaries = castingBounds;
Derek Sollenbergerc31985e2021-05-18 16:38:17 -04001372 shadowLayer.skipContentDraw = true;
Alec Mouribd17b3b2020-12-17 11:08:30 -08001373 shadowLayer.alpha = 1.0f;
1374 ColorSourceVariant::fillColor(shadowLayer, 0, 0, 0, this);
1375 shadowLayer.shadow = shadow;
Sally Qi59a9f502021-10-12 18:53:23 +00001376 layers.push_back(shadowLayer);
Alec Mouribd17b3b2020-12-17 11:08:30 -08001377
Alec Mouric0aae732021-01-12 13:32:18 -08001378 invokeDraw(settings, layers);
Alec Mouribd17b3b2020-12-17 11:08:30 -08001379}
1380
Alec Mouri5a493722022-01-26 16:43:02 -08001381void RenderEngineTest::tonemap(ui::Dataspace sourceDataspace, std::function<vec3(vec3)> eotf,
1382 std::function<vec3(vec3, float)> scaleOotf) {
1383 constexpr int32_t kGreyLevels = 256;
1384
1385 const auto rect = Rect(0, 0, kGreyLevels, 1);
1386
1387 constexpr float kMaxLuminance = 750.f;
1388 constexpr float kCurrentLuminanceNits = 500.f;
1389 const renderengine::DisplaySettings display{
1390 .physicalDisplay = rect,
1391 .clip = rect,
1392 .maxLuminance = kMaxLuminance,
1393 .currentLuminanceNits = kCurrentLuminanceNits,
1394 .outputDataspace = ui::Dataspace::DISPLAY_P3,
1395 };
1396
1397 auto buf = std::make_shared<
1398 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07001399 ExternalTexture>(sp<GraphicBuffer>::make(kGreyLevels, 1,
1400 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1401 GRALLOC_USAGE_SW_READ_OFTEN |
1402 GRALLOC_USAGE_SW_WRITE_OFTEN |
1403 GRALLOC_USAGE_HW_RENDER |
1404 GRALLOC_USAGE_HW_TEXTURE,
1405 "input"),
Alec Mouri5a493722022-01-26 16:43:02 -08001406 *mRE,
1407 renderengine::impl::ExternalTexture::Usage::READABLE |
1408 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
1409 ASSERT_EQ(0, buf->getBuffer()->initCheck());
1410 {
1411 uint8_t* pixels;
1412 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1413 reinterpret_cast<void**>(&pixels));
1414
1415 uint8_t color = 0;
1416 for (int32_t j = 0; j < buf->getBuffer()->getHeight(); j++) {
1417 uint8_t* dest = pixels + (buf->getBuffer()->getStride() * j * 4);
1418 for (int32_t i = 0; i < buf->getBuffer()->getWidth(); i++) {
1419 dest[0] = color;
1420 dest[1] = color;
1421 dest[2] = color;
1422 dest[3] = 255;
1423 color++;
1424 dest += 4;
1425 }
1426 }
1427 buf->getBuffer()->unlock();
1428 }
1429
1430 mBuffer = std::make_shared<
1431 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07001432 ExternalTexture>(sp<GraphicBuffer>::make(kGreyLevels, 1,
1433 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1434 GRALLOC_USAGE_SW_READ_OFTEN |
1435 GRALLOC_USAGE_SW_WRITE_OFTEN |
1436 GRALLOC_USAGE_HW_RENDER |
1437 GRALLOC_USAGE_HW_TEXTURE,
1438 "output"),
Alec Mouri5a493722022-01-26 16:43:02 -08001439 *mRE,
1440 renderengine::impl::ExternalTexture::Usage::READABLE |
1441 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
1442 ASSERT_EQ(0, mBuffer->getBuffer()->initCheck());
1443
1444 const renderengine::LayerSettings layer{.geometry.boundaries = rect.toFloatRect(),
1445 .source =
1446 renderengine::PixelSource{
1447 .buffer =
1448 renderengine::Buffer{
1449 .buffer =
1450 std::move(buf),
1451 .usePremultipliedAlpha =
1452 true,
1453 },
1454 },
1455 .alpha = 1.0f,
1456 .sourceDataspace = sourceDataspace};
1457
1458 std::vector<renderengine::LayerSettings> layers{layer};
1459 invokeDraw(display, layers);
1460
1461 ColorSpace displayP3 = ColorSpace::DisplayP3();
1462 ColorSpace bt2020 = ColorSpace::BT2020();
1463
1464 tonemap::Metadata metadata{.displayMaxLuminance = 750.0f};
1465
1466 auto generator = [=](Point location) {
1467 const double normColor = static_cast<double>(location.x) / (kGreyLevels - 1);
1468 const vec3 rgb = vec3(normColor, normColor, normColor);
1469
1470 const vec3 linearRGB = eotf(rgb);
1471
1472 const vec3 xyz = bt2020.getRGBtoXYZ() * linearRGB;
1473
1474 const vec3 scaledXYZ = scaleOotf(xyz, kCurrentLuminanceNits);
Alec Mouri196b0f22022-03-04 22:13:48 +00001475 const auto gains =
Alec Mouri5a493722022-01-26 16:43:02 -08001476 tonemap::getToneMapper()
1477 ->lookupTonemapGain(static_cast<aidl::android::hardware::graphics::common::
1478 Dataspace>(sourceDataspace),
1479 static_cast<aidl::android::hardware::graphics::common::
1480 Dataspace>(
1481 ui::Dataspace::DISPLAY_P3),
Alec Mouri196b0f22022-03-04 22:13:48 +00001482 {tonemap::
1483 Color{.linearRGB =
1484 scaleOotf(linearRGB,
1485 kCurrentLuminanceNits),
1486 .xyz = scaledXYZ}},
Alec Mouri5a493722022-01-26 16:43:02 -08001487 metadata);
Alec Mouri196b0f22022-03-04 22:13:48 +00001488 EXPECT_EQ(1, gains.size());
1489 const double gain = gains.front();
Alec Mouri5a493722022-01-26 16:43:02 -08001490 const vec3 normalizedXYZ = scaledXYZ * gain / metadata.displayMaxLuminance;
1491
1492 const vec3 targetRGB = OETF_sRGB(displayP3.getXYZtoRGB() * normalizedXYZ) * 255;
1493 return ubyte4(static_cast<uint8_t>(targetRGB.r), static_cast<uint8_t>(targetRGB.g),
1494 static_cast<uint8_t>(targetRGB.b), 255);
1495 };
1496
1497 expectBufferColor(Rect(kGreyLevels, 1), generator, 2);
1498}
1499
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001500INSTANTIATE_TEST_SUITE_P(PerRenderEngineType, RenderEngineTest,
Alec Mouric16974e2022-09-13 17:35:48 +00001501 testing::Values(std::make_shared<SkiaGLESRenderEngineFactory>(),
Nolan Scobie195631a2024-03-26 12:22:23 -04001502 std::make_shared<GaneshVkRenderEngineFactory>(),
1503 std::make_shared<GraphiteVkRenderEngineFactory>()));
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001504
1505TEST_P(RenderEngineTest, drawLayers_noLayersToDraw) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001506 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001507 GTEST_SKIP();
1508 }
Alec Mouric0aae732021-01-12 13:32:18 -08001509 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001510 drawEmptyLayers();
1511}
1512
Sally Qi1fed86e2022-06-23 15:33:52 -07001513TEST_P(RenderEngineTest, drawLayers_fillRedBufferAndEmptyBuffer) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001514 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001515 GTEST_SKIP();
1516 }
Sally Qi1fed86e2022-06-23 15:33:52 -07001517 initializeRenderEngine();
1518 renderengine::DisplaySettings settings;
1519 settings.physicalDisplay = fullscreenRect();
1520 settings.clip = fullscreenRect();
1521 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1522
1523 // add a red layer
1524 renderengine::LayerSettings layerOne{
1525 .geometry.boundaries = fullscreenRect().toFloatRect(),
1526 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
1527 .alpha = 1.f,
1528 };
1529
1530 std::vector<renderengine::LayerSettings> layersFirst{layerOne};
1531 invokeDraw(settings, layersFirst);
1532 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
1533
1534 // re-draw with an empty layer above it, and we get a transparent black one
1535 std::vector<renderengine::LayerSettings> layersSecond;
1536 invokeDraw(settings, layersSecond);
1537 expectBufferColor(fullscreenRect(), 0, 0, 0, 0);
1538}
1539
Ana Krulec07b98df2021-01-07 14:38:40 -08001540TEST_P(RenderEngineTest, drawLayers_withoutBuffers_withColorTransform) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001541 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001542 GTEST_SKIP();
1543 }
Alec Mouria90a5702021-04-16 16:36:21 +00001544 initializeRenderEngine();
Ana Krulec07b98df2021-01-07 14:38:40 -08001545
1546 renderengine::DisplaySettings settings;
1547 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1548 settings.physicalDisplay = fullscreenRect();
1549 settings.clip = fullscreenRect();
1550
1551 // 255, 255, 255, 255 is full opaque white.
Alec Mouri4049b532021-10-15 20:59:33 -07001552 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
1553 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Ana Krulec07b98df2021-01-07 14:38:40 -08001554 // Create layer with given color.
1555 renderengine::LayerSettings bgLayer;
1556 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1557 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1558 bgLayer.source.solidColor = half3(backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1559 backgroundColor.b / 255.0f);
1560 bgLayer.alpha = backgroundColor.a / 255.0f;
1561 // Transform the red color.
1562 bgLayer.colorTransform = mat4(-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
1563
Sally Qi59a9f502021-10-12 18:53:23 +00001564 std::vector<renderengine::LayerSettings> layers;
1565 layers.push_back(bgLayer);
Ana Krulec07b98df2021-01-07 14:38:40 -08001566
Alec Mouric0aae732021-01-12 13:32:18 -08001567 invokeDraw(settings, layers);
Ana Krulec07b98df2021-01-07 14:38:40 -08001568
1569 // Expect to see full opaque pixel (with inverted red from the transform).
Alec Mouric0aae732021-01-12 13:32:18 -08001570 expectBufferColor(Rect(0, 0, 10, 10), 0.f, backgroundColor.g, backgroundColor.b,
Ana Krulec07b98df2021-01-07 14:38:40 -08001571 backgroundColor.a);
1572}
1573
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001574TEST_P(RenderEngineTest, drawLayers_nullOutputBuffer) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001575 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001576 GTEST_SKIP();
1577 }
Alec Mouric0aae732021-01-12 13:32:18 -08001578 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001579
Alec Mourid43ccab2019-03-13 12:23:45 -07001580 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001581 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Sally Qi59a9f502021-10-12 18:53:23 +00001582 std::vector<renderengine::LayerSettings> layers;
Alec Mourid43ccab2019-03-13 12:23:45 -07001583 renderengine::LayerSettings layer;
1584 layer.geometry.boundaries = fullscreenRect().toFloatRect();
1585 BufferSourceVariant<ForceOpaqueBufferVariant>::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
Sally Qi59a9f502021-10-12 18:53:23 +00001586 layers.push_back(layer);
Alec Mourif29700f2023-08-17 21:53:31 +00001587 ftl::Future<FenceResult> future = mRE->drawLayers(settings, layers, nullptr, base::unique_fd());
Alec Mourid43ccab2019-03-13 12:23:45 -07001588
Patrick Williams2e9748f2022-08-09 22:48:18 +00001589 ASSERT_TRUE(future.valid());
1590 auto result = future.get();
1591 ASSERT_FALSE(result.ok());
1592 ASSERT_EQ(BAD_VALUE, result.error());
Alec Mourid43ccab2019-03-13 12:23:45 -07001593}
1594
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001595TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001596 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001597 GTEST_SKIP();
1598 }
Alec Mouric0aae732021-01-12 13:32:18 -08001599 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001600 fillRedBuffer<ColorSourceVariant>();
1601}
1602
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001603TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001604 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001605 GTEST_SKIP();
1606 }
Alec Mouric0aae732021-01-12 13:32:18 -08001607 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001608 fillGreenBuffer<ColorSourceVariant>();
1609}
1610
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001611TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001612 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001613 GTEST_SKIP();
1614 }
Alec Mouric0aae732021-01-12 13:32:18 -08001615 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001616 fillBlueBuffer<ColorSourceVariant>();
1617}
1618
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001619TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001620 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001621 GTEST_SKIP();
1622 }
Alec Mouric0aae732021-01-12 13:32:18 -08001623 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001624 fillRedTransparentBuffer<ColorSourceVariant>();
1625}
1626
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001627TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001628 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001629 GTEST_SKIP();
1630 }
Alec Mouric0aae732021-01-12 13:32:18 -08001631 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001632 fillBufferPhysicalOffset<ColorSourceVariant>();
1633}
1634
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001635TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001636 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001637 GTEST_SKIP();
1638 }
Alec Mouric0aae732021-01-12 13:32:18 -08001639 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001640 fillBufferCheckersRotate0<ColorSourceVariant>();
1641}
1642
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001643TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001644 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001645 GTEST_SKIP();
1646 }
Alec Mouric0aae732021-01-12 13:32:18 -08001647 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001648 fillBufferCheckersRotate90<ColorSourceVariant>();
1649}
1650
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001651TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001652 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001653 GTEST_SKIP();
1654 }
Alec Mouric0aae732021-01-12 13:32:18 -08001655 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001656 fillBufferCheckersRotate180<ColorSourceVariant>();
1657}
1658
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001659TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001660 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001661 GTEST_SKIP();
1662 }
Alec Mouric0aae732021-01-12 13:32:18 -08001663 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001664 fillBufferCheckersRotate270<ColorSourceVariant>();
1665}
1666
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001667TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001668 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001669 GTEST_SKIP();
1670 }
Alec Mouric0aae732021-01-12 13:32:18 -08001671 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001672 fillBufferLayerTransform<ColorSourceVariant>();
1673}
1674
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001675TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001676 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001677 GTEST_SKIP();
1678 }
Alec Mouric0aae732021-01-12 13:32:18 -08001679 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08001680 fillBufferColorTransform<ColorSourceVariant>();
1681}
1682
Sally Qi2019fd22021-11-22 10:19:04 -08001683TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_sourceDataspace) {
1684 const auto& renderEngineFactory = GetParam();
1685 // skip for non color management
Leon Scroggins III696bf932024-01-24 15:21:05 -05001686 if (!renderEngineFactory->apiSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001687 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001688 }
1689
1690 initializeRenderEngine();
1691 fillBufferColorTransformAndSourceDataspace<ColorSourceVariant>();
1692}
1693
1694TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_outputDataspace) {
1695 const auto& renderEngineFactory = GetParam();
1696 // skip for non color management
Leon Scroggins III696bf932024-01-24 15:21:05 -05001697 if (!renderEngineFactory->apiSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001698 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001699 }
1700
1701 initializeRenderEngine();
1702 fillBufferColorTransformAndOutputDataspace<ColorSourceVariant>();
1703}
1704
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001705TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001706 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001707 GTEST_SKIP();
1708 }
Alec Mouric0aae732021-01-12 13:32:18 -08001709 initializeRenderEngine();
Alec Mouri7c94edb2018-12-03 21:23:26 -08001710 fillBufferWithRoundedCorners<ColorSourceVariant>();
1711}
1712
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001713TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001714 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001715 GTEST_SKIP();
1716 }
Alec Mouric0aae732021-01-12 13:32:18 -08001717 initializeRenderEngine();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001718 fillBufferColorTransformZeroLayerAlpha<ColorSourceVariant>();
1719}
1720
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001721TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001722 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001723 GTEST_SKIP();
1724 }
Alec Mouric0aae732021-01-12 13:32:18 -08001725 initializeRenderEngine();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001726 fillBufferAndBlurBackground<ColorSourceVariant>();
1727}
1728
Alec Mourie8489fd2021-04-29 16:08:56 -07001729TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001730 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001731 GTEST_SKIP();
1732 }
Alec Mourie8489fd2021-04-29 16:08:56 -07001733 initializeRenderEngine();
1734 fillSmallLayerAndBlurBackground<ColorSourceVariant>();
1735}
1736
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001737TEST_P(RenderEngineTest, drawLayers_overlayCorners_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001738 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001739 GTEST_SKIP();
1740 }
Alec Mouric0aae732021-01-12 13:32:18 -08001741 initializeRenderEngine();
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001742 overlayCorners<ColorSourceVariant>();
1743}
1744
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001745TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001746 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001747 GTEST_SKIP();
1748 }
Alec Mouric0aae732021-01-12 13:32:18 -08001749 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001750 fillRedBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1751}
1752
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001753TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001754 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001755 GTEST_SKIP();
1756 }
Alec Mouric0aae732021-01-12 13:32:18 -08001757 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001758 fillGreenBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1759}
1760
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001761TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001762 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001763 GTEST_SKIP();
1764 }
Alec Mouric0aae732021-01-12 13:32:18 -08001765 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001766 fillBlueBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1767}
1768
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001769TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001770 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001771 GTEST_SKIP();
1772 }
Alec Mouric0aae732021-01-12 13:32:18 -08001773 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001774 fillRedTransparentBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1775}
1776
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001777TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001778 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001779 GTEST_SKIP();
1780 }
Alec Mouric0aae732021-01-12 13:32:18 -08001781 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001782 fillBufferPhysicalOffset<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1783}
1784
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001785TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001786 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001787 GTEST_SKIP();
1788 }
Alec Mouric0aae732021-01-12 13:32:18 -08001789 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001790 fillBufferCheckersRotate0<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1791}
1792
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001793TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001794 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001795 GTEST_SKIP();
1796 }
Alec Mouric0aae732021-01-12 13:32:18 -08001797 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001798 fillBufferCheckersRotate90<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1799}
1800
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001801TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001802 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001803 GTEST_SKIP();
1804 }
Alec Mouric0aae732021-01-12 13:32:18 -08001805 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001806 fillBufferCheckersRotate180<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1807}
1808
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001809TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001810 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001811 GTEST_SKIP();
1812 }
Alec Mouric0aae732021-01-12 13:32:18 -08001813 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001814 fillBufferCheckersRotate270<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1815}
1816
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001817TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001818 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001819 GTEST_SKIP();
1820 }
Alec Mouric0aae732021-01-12 13:32:18 -08001821 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001822 fillBufferLayerTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1823}
1824
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001825TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001826 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001827 GTEST_SKIP();
1828 }
Alec Mouric0aae732021-01-12 13:32:18 -08001829 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08001830 fillBufferColorTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1831}
1832
Sally Qi2019fd22021-11-22 10:19:04 -08001833TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndSourceDataspace_opaqueBufferSource) {
1834 const auto& renderEngineFactory = GetParam();
1835 // skip for non color management
Leon Scroggins III696bf932024-01-24 15:21:05 -05001836 if (!renderEngineFactory->apiSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001837 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001838 }
1839
1840 initializeRenderEngine();
1841 fillBufferColorTransformAndSourceDataspace<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1842}
1843
1844TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndOutputDataspace_opaqueBufferSource) {
1845 const auto& renderEngineFactory = GetParam();
1846 // skip for non color management
Leon Scroggins III696bf932024-01-24 15:21:05 -05001847 if (!renderEngineFactory->apiSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001848 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001849 }
1850
1851 initializeRenderEngine();
1852 fillBufferColorTransformAndOutputDataspace<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1853}
1854
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001855TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001856 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001857 GTEST_SKIP();
1858 }
Alec Mouric0aae732021-01-12 13:32:18 -08001859 initializeRenderEngine();
Alec Mouri7c94edb2018-12-03 21:23:26 -08001860 fillBufferWithRoundedCorners<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1861}
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001862
Alec Mouric0aae732021-01-12 13:32:18 -08001863TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001864 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001865 GTEST_SKIP();
1866 }
Alec Mouric0aae732021-01-12 13:32:18 -08001867 initializeRenderEngine();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001868 fillBufferColorTransformZeroLayerAlpha<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1869}
Alec Mouri7c94edb2018-12-03 21:23:26 -08001870
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001871TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001872 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001873 GTEST_SKIP();
1874 }
Alec Mouric0aae732021-01-12 13:32:18 -08001875 initializeRenderEngine();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001876 fillBufferAndBlurBackground<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1877}
1878
Alec Mourie8489fd2021-04-29 16:08:56 -07001879TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001880 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001881 GTEST_SKIP();
1882 }
Alec Mourie8489fd2021-04-29 16:08:56 -07001883 initializeRenderEngine();
1884 fillSmallLayerAndBlurBackground<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1885}
1886
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001887TEST_P(RenderEngineTest, drawLayers_overlayCorners_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001888 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001889 GTEST_SKIP();
1890 }
Alec Mouric0aae732021-01-12 13:32:18 -08001891 initializeRenderEngine();
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001892 overlayCorners<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1893}
1894
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001895TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001896 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001897 GTEST_SKIP();
1898 }
Alec Mouric0aae732021-01-12 13:32:18 -08001899 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001900 fillRedBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1901}
1902
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001903TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001904 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001905 GTEST_SKIP();
1906 }
Alec Mouric0aae732021-01-12 13:32:18 -08001907 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001908 fillGreenBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1909}
1910
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001911TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001912 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001913 GTEST_SKIP();
1914 }
Alec Mouric0aae732021-01-12 13:32:18 -08001915 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001916 fillBlueBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1917}
1918
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001919TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001920 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001921 GTEST_SKIP();
1922 }
Alec Mouric0aae732021-01-12 13:32:18 -08001923 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001924 fillRedTransparentBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1925}
1926
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001927TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001928 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001929 GTEST_SKIP();
1930 }
Alec Mouric0aae732021-01-12 13:32:18 -08001931 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001932 fillBufferPhysicalOffset<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1933}
1934
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001935TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001936 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001937 GTEST_SKIP();
1938 }
Alec Mouric0aae732021-01-12 13:32:18 -08001939 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001940 fillBufferCheckersRotate0<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1941}
1942
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001943TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001944 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001945 GTEST_SKIP();
1946 }
Alec Mouric0aae732021-01-12 13:32:18 -08001947 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001948 fillBufferCheckersRotate90<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1949}
1950
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001951TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001952 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001953 GTEST_SKIP();
1954 }
Alec Mouric0aae732021-01-12 13:32:18 -08001955 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001956 fillBufferCheckersRotate180<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1957}
1958
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001959TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001960 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001961 GTEST_SKIP();
1962 }
Alec Mouric0aae732021-01-12 13:32:18 -08001963 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001964 fillBufferCheckersRotate270<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1965}
1966
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001967TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001968 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001969 GTEST_SKIP();
1970 }
Alec Mouric0aae732021-01-12 13:32:18 -08001971 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001972 fillBufferLayerTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1973}
1974
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001975TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001976 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001977 GTEST_SKIP();
1978 }
Alec Mouric0aae732021-01-12 13:32:18 -08001979 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08001980 fillBufferColorTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1981}
1982
Sally Qi2019fd22021-11-22 10:19:04 -08001983TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndSourceDataspace_bufferSource) {
1984 const auto& renderEngineFactory = GetParam();
1985 // skip for non color management
Leon Scroggins III696bf932024-01-24 15:21:05 -05001986 if (!renderEngineFactory->apiSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001987 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001988 }
1989
1990 initializeRenderEngine();
1991 fillBufferColorTransformAndSourceDataspace<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1992}
1993
1994TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndOutputDataspace_bufferSource) {
1995 const auto& renderEngineFactory = GetParam();
1996 // skip for non color management
Leon Scroggins III696bf932024-01-24 15:21:05 -05001997 if (!renderEngineFactory->apiSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001998 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001999 }
2000
2001 initializeRenderEngine();
2002 fillBufferColorTransformAndOutputDataspace<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2003}
2004
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002005TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002006 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002007 GTEST_SKIP();
2008 }
Alec Mouric0aae732021-01-12 13:32:18 -08002009 initializeRenderEngine();
Alec Mouri7c94edb2018-12-03 21:23:26 -08002010 fillBufferWithRoundedCorners<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2011}
2012
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08002013TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002014 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002015 GTEST_SKIP();
2016 }
Alec Mouric0aae732021-01-12 13:32:18 -08002017 initializeRenderEngine();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08002018 fillBufferColorTransformZeroLayerAlpha<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2019}
2020
Nathaniel Nifong53494f32021-04-30 14:05:39 -04002021TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002022 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002023 GTEST_SKIP();
2024 }
Alec Mouric0aae732021-01-12 13:32:18 -08002025 initializeRenderEngine();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08002026 fillBufferAndBlurBackground<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2027}
2028
Alec Mourie8489fd2021-04-29 16:08:56 -07002029TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002030 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002031 GTEST_SKIP();
2032 }
Alec Mourie8489fd2021-04-29 16:08:56 -07002033 initializeRenderEngine();
2034 fillSmallLayerAndBlurBackground<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2035}
2036
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002037TEST_P(RenderEngineTest, drawLayers_overlayCorners_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002038 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002039 GTEST_SKIP();
2040 }
Alec Mouric0aae732021-01-12 13:32:18 -08002041 initializeRenderEngine();
Alec Mourie7d1d4a2019-02-05 01:13:46 +00002042 overlayCorners<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2043}
2044
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002045TEST_P(RenderEngineTest, drawLayers_fillBufferTextureTransform) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002046 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002047 GTEST_SKIP();
2048 }
Alec Mouric0aae732021-01-12 13:32:18 -08002049 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002050 fillBufferTextureTransform();
2051}
2052
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002053TEST_P(RenderEngineTest, drawLayers_fillBuffer_premultipliesAlpha) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002054 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002055 GTEST_SKIP();
2056 }
Alec Mouric0aae732021-01-12 13:32:18 -08002057 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002058 fillBufferWithPremultiplyAlpha();
2059}
2060
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002061TEST_P(RenderEngineTest, drawLayers_fillBuffer_withoutPremultiplyingAlpha) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002062 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002063 GTEST_SKIP();
2064 }
Alec Mouric0aae732021-01-12 13:32:18 -08002065 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002066 fillBufferWithoutPremultiplyAlpha();
2067}
2068
Alec Mouribd17b3b2020-12-17 11:08:30 -08002069TEST_P(RenderEngineTest, drawLayers_fillShadow_castsWithoutCasterLayer) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002070 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002071 GTEST_SKIP();
2072 }
Alec Mouric0aae732021-01-12 13:32:18 -08002073 initializeRenderEngine();
Alec Mouribd17b3b2020-12-17 11:08:30 -08002074
Alec Mouri4049b532021-10-15 20:59:33 -07002075 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2076 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Alec Mouribd17b3b2020-12-17 11:08:30 -08002077 const float shadowLength = 5.0f;
2078 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2079 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
Vishnu Naird9e4f462023-10-06 04:05:45 +00002080 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2081 shadowLength, false /* casterIsTranslucent */);
Alec Mouribd17b3b2020-12-17 11:08:30 -08002082
2083 drawShadowWithoutCaster(casterBounds.toFloatRect(), settings, backgroundColor);
2084 expectShadowColorWithoutCaster(casterBounds.toFloatRect(), settings, backgroundColor);
2085}
2086
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002087TEST_P(RenderEngineTest, drawLayers_fillShadow_casterLayerMinSize) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002088 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002089 GTEST_SKIP();
2090 }
Alec Mouric0aae732021-01-12 13:32:18 -08002091 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002092
Alec Mouri4049b532021-10-15 20:59:33 -07002093 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2094 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2095 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2096 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002097 const float shadowLength = 5.0f;
2098 Rect casterBounds(1, 1);
2099 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2100 renderengine::LayerSettings castingLayer;
2101 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2102 castingLayer.alpha = 1.0f;
Vishnu Naird9e4f462023-10-06 04:05:45 +00002103 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2104 shadowLength, false /* casterIsTranslucent */);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002105
2106 drawShadow<ColorSourceVariant>(castingLayer, settings, casterColor, backgroundColor);
2107 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2108}
2109
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002110TEST_P(RenderEngineTest, drawLayers_fillShadow_casterColorLayer) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002111 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002112 GTEST_SKIP();
2113 }
Alec Mouric0aae732021-01-12 13:32:18 -08002114 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002115
Alec Mouri4049b532021-10-15 20:59:33 -07002116 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2117 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2118 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2119 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002120 const float shadowLength = 5.0f;
2121 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2122 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2123 renderengine::LayerSettings castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002124 castingLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002125 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2126 castingLayer.alpha = 1.0f;
Vishnu Naird9e4f462023-10-06 04:05:45 +00002127 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2128 shadowLength, false /* casterIsTranslucent */);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002129
2130 drawShadow<ColorSourceVariant>(castingLayer, settings, casterColor, backgroundColor);
2131 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2132}
2133
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002134TEST_P(RenderEngineTest, drawLayers_fillShadow_casterOpaqueBufferLayer) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002135 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002136 GTEST_SKIP();
2137 }
Alec Mouric0aae732021-01-12 13:32:18 -08002138 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002139
Alec Mouri4049b532021-10-15 20:59:33 -07002140 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2141 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2142 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2143 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002144 const float shadowLength = 5.0f;
2145 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2146 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2147 renderengine::LayerSettings castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002148 castingLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002149 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2150 castingLayer.alpha = 1.0f;
Vishnu Naird9e4f462023-10-06 04:05:45 +00002151 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2152 shadowLength, false /* casterIsTranslucent */);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002153
2154 drawShadow<BufferSourceVariant<ForceOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2155 backgroundColor);
2156 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2157}
2158
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002159TEST_P(RenderEngineTest, drawLayers_fillShadow_casterWithRoundedCorner) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002160 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002161 GTEST_SKIP();
2162 }
Alec Mouric0aae732021-01-12 13:32:18 -08002163 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002164
Alec Mouri4049b532021-10-15 20:59:33 -07002165 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2166 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2167 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2168 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002169 const float shadowLength = 5.0f;
2170 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2171 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2172 renderengine::LayerSettings castingLayer;
2173 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002174 castingLayer.geometry.roundedCornersRadius = {3.0f, 3.0f};
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002175 castingLayer.geometry.roundedCornersCrop = casterBounds.toFloatRect();
2176 castingLayer.alpha = 1.0f;
Vishnu Naird9e4f462023-10-06 04:05:45 +00002177 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2178 shadowLength, false /* casterIsTranslucent */);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002179
2180 drawShadow<BufferSourceVariant<ForceOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2181 backgroundColor);
2182 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2183}
2184
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002185TEST_P(RenderEngineTest, drawLayers_fillShadow_translucentCasterWithAlpha) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002186 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002187 GTEST_SKIP();
2188 }
Alec Mouric0aae732021-01-12 13:32:18 -08002189 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002190
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002191 const ubyte4 casterColor(255, 0, 0, 255);
2192 const ubyte4 backgroundColor(255, 255, 255, 255);
2193 const float shadowLength = 5.0f;
2194 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2195 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2196 renderengine::LayerSettings castingLayer;
2197 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2198 castingLayer.alpha = 0.5f;
Vishnu Naird9e4f462023-10-06 04:05:45 +00002199 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2200 shadowLength, true /* casterIsTranslucent */);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002201
2202 drawShadow<BufferSourceVariant<RelaxOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2203 backgroundColor);
2204
2205 // verify only the background since the shadow will draw behind the caster
2206 const float shadowInset = settings.length * -1.0f;
2207 const Rect casterWithShadow =
2208 Rect(casterBounds).inset(shadowInset, shadowInset, shadowInset, shadowInset);
2209 const Region backgroundRegion = Region(fullscreenRect()).subtractSelf(casterWithShadow);
2210 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
2211 backgroundColor.a);
2212}
2213
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002214TEST_P(RenderEngineTest, cleanupPostRender_cleansUpOnce) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002215 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002216 GTEST_SKIP();
2217 }
Alec Mouric0aae732021-01-12 13:32:18 -08002218 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002219
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002220 renderengine::DisplaySettings settings;
2221 settings.physicalDisplay = fullscreenRect();
2222 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002223 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002224
Sally Qi59a9f502021-10-12 18:53:23 +00002225 std::vector<renderengine::LayerSettings> layers;
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002226 renderengine::LayerSettings layer;
2227 layer.geometry.boundaries = fullscreenRect().toFloatRect();
2228 BufferSourceVariant<ForceOpaqueBufferVariant>::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
2229 layer.alpha = 1.0;
Sally Qi59a9f502021-10-12 18:53:23 +00002230 layers.push_back(layer);
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002231
Patrick Williams2e9748f2022-08-09 22:48:18 +00002232 ftl::Future<FenceResult> futureOne =
Alec Mourif29700f2023-08-17 21:53:31 +00002233 mRE->drawLayers(settings, layers, mBuffer, base::unique_fd());
Patrick Williams2e9748f2022-08-09 22:48:18 +00002234 ASSERT_TRUE(futureOne.valid());
2235 auto resultOne = futureOne.get();
2236 ASSERT_TRUE(resultOne.ok());
2237 auto fenceOne = resultOne.value();
Sally Qi4cabdd02021-08-05 16:45:57 -07002238
Patrick Williams2e9748f2022-08-09 22:48:18 +00002239 ftl::Future<FenceResult> futureTwo =
Alec Mourif29700f2023-08-17 21:53:31 +00002240 mRE->drawLayers(settings, layers, mBuffer, base::unique_fd(fenceOne->dup()));
Patrick Williams2e9748f2022-08-09 22:48:18 +00002241 ASSERT_TRUE(futureTwo.valid());
2242 auto resultTwo = futureTwo.get();
2243 ASSERT_TRUE(resultTwo.ok());
2244 auto fenceTwo = resultTwo.value();
2245 fenceTwo->waitForever(LOG_TAG);
Derek Sollenbergerec411212021-08-25 10:54:47 -04002246
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002247 // Only cleanup the first time.
Ian Elliott1f0911e2022-09-09 16:31:47 -06002248 if (mRE->canSkipPostRenderCleanup()) {
2249 // Skia's Vk backend may keep the texture alive beyond drawLayersInternal, so
2250 // it never gets added to the cleanup list. In those cases, we can skip.
Leon Scroggins III696bf932024-01-24 15:21:05 -05002251 EXPECT_TRUE(GetParam()->graphicsApi() == renderengine::RenderEngine::GraphicsApi::VK);
Ian Elliott1f0911e2022-09-09 16:31:47 -06002252 } else {
2253 mRE->cleanupPostRender();
2254 EXPECT_TRUE(mRE->canSkipPostRenderCleanup());
2255 }
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002256}
2257
Ana Krulecf9a15d92020-12-11 08:35:00 -08002258TEST_P(RenderEngineTest, testRoundedCornersCrop) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002259 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002260 GTEST_SKIP();
2261 }
Alec Mouric0aae732021-01-12 13:32:18 -08002262 initializeRenderEngine();
Ana Krulecf9a15d92020-12-11 08:35:00 -08002263
2264 renderengine::DisplaySettings settings;
2265 settings.physicalDisplay = fullscreenRect();
2266 settings.clip = fullscreenRect();
2267 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2268
Sally Qi59a9f502021-10-12 18:53:23 +00002269 std::vector<renderengine::LayerSettings> layers;
Ana Krulecf9a15d92020-12-11 08:35:00 -08002270
2271 renderengine::LayerSettings redLayer;
2272 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2273 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002274 redLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
2275
Ana Krulecf9a15d92020-12-11 08:35:00 -08002276 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2277 // Red background.
2278 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2279 redLayer.alpha = 1.0f;
2280
Sally Qi59a9f502021-10-12 18:53:23 +00002281 layers.push_back(redLayer);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002282
2283 // Green layer with 1/3 size.
2284 renderengine::LayerSettings greenLayer;
2285 greenLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2286 greenLayer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002287 greenLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
Ana Krulecf9a15d92020-12-11 08:35:00 -08002288 // Bottom right corner is not going to be rounded.
2289 greenLayer.geometry.roundedCornersCrop =
2290 Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3, DEFAULT_DISPLAY_HEIGHT,
2291 DEFAULT_DISPLAY_HEIGHT)
2292 .toFloatRect();
2293 greenLayer.source.solidColor = half3(0.0f, 1.0f, 0.0f);
2294 greenLayer.alpha = 1.0f;
2295
Sally Qi59a9f502021-10-12 18:53:23 +00002296 layers.push_back(greenLayer);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002297
Alec Mouric0aae732021-01-12 13:32:18 -08002298 invokeDraw(settings, layers);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002299
2300 // Corners should be ignored...
2301 // Screen size: width is 128, height is 256.
2302 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 0);
2303 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, 0, DEFAULT_DISPLAY_WIDTH, 1), 0, 0, 0, 0);
2304 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT - 1, 1, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
2305 // Bottom right corner is kept out of the clipping, and it's green.
2306 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1,
2307 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
2308 0, 255, 0, 255);
2309}
2310
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002311TEST_P(RenderEngineTest, testRoundedCornersParentCrop) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002312 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002313 GTEST_SKIP();
2314 }
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002315 initializeRenderEngine();
2316
2317 renderengine::DisplaySettings settings;
2318 settings.physicalDisplay = fullscreenRect();
2319 settings.clip = fullscreenRect();
2320 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2321
Sally Qi59a9f502021-10-12 18:53:23 +00002322 std::vector<renderengine::LayerSettings> layers;
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002323
2324 renderengine::LayerSettings redLayer;
2325 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2326 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002327 redLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002328 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2329 // Red background.
2330 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2331 redLayer.alpha = 1.0f;
2332
Sally Qi59a9f502021-10-12 18:53:23 +00002333 layers.push_back(redLayer);
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002334
2335 // Green layer with 1/2 size with parent crop rect.
2336 renderengine::LayerSettings greenLayer = redLayer;
2337 greenLayer.geometry.boundaries =
2338 FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT / 2);
2339 greenLayer.source.solidColor = half3(0.0f, 1.0f, 0.0f);
2340
Sally Qi59a9f502021-10-12 18:53:23 +00002341 layers.push_back(greenLayer);
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002342
2343 invokeDraw(settings, layers);
2344
2345 // Due to roundedCornersRadius, the corners are untouched.
2346 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2347 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2348 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2349 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2350
2351 // top middle should be green and the bottom middle red
2352 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, 0), 0, 255, 0, 255);
2353 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0, 255);
2354
2355 // the bottom edge of the green layer should not be rounded
2356 expectBufferColor(Point(0, (DEFAULT_DISPLAY_HEIGHT / 2) - 1), 0, 255, 0, 255);
2357}
2358
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002359TEST_P(RenderEngineTest, testRoundedCornersParentCropSmallBounds) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002360 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002361 GTEST_SKIP();
2362 }
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002363 initializeRenderEngine();
2364
2365 renderengine::DisplaySettings settings;
2366 settings.physicalDisplay = fullscreenRect();
2367 settings.clip = fullscreenRect();
2368 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2369
Sally Qi59a9f502021-10-12 18:53:23 +00002370 std::vector<renderengine::LayerSettings> layers;
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002371
2372 renderengine::LayerSettings redLayer;
2373 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2374 redLayer.geometry.boundaries = FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, 32);
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002375 redLayer.geometry.roundedCornersRadius = {64.0f, 64.0f};
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002376 redLayer.geometry.roundedCornersCrop = FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, 128);
2377 // Red background.
2378 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2379 redLayer.alpha = 1.0f;
2380
Sally Qi59a9f502021-10-12 18:53:23 +00002381 layers.push_back(redLayer);
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002382 invokeDraw(settings, layers);
2383
2384 // Due to roundedCornersRadius, the top corners are untouched.
2385 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2386 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2387
2388 // ensure that the entire height of the red layer was clipped by the rounded corners crop.
2389 expectBufferColor(Point(0, 31), 0, 0, 0, 0);
2390 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 31), 0, 0, 0, 0);
2391
2392 // the bottom middle should be red
2393 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, 31), 255, 0, 0, 255);
2394}
2395
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002396TEST_P(RenderEngineTest, testRoundedCornersXY) {
Leon Scroggins III9ba31e32024-01-25 11:40:26 -05002397 if (!GetParam()->apiSupported()) {
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002398 GTEST_SKIP();
2399 }
2400
2401 initializeRenderEngine();
2402
2403 renderengine::DisplaySettings settings;
2404 settings.physicalDisplay = fullscreenRect();
2405 settings.clip = fullscreenRect();
2406 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2407
2408 std::vector<renderengine::LayerSettings> layers;
2409
2410 renderengine::LayerSettings redLayer;
2411 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2412 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
2413 redLayer.geometry.roundedCornersRadius = {5.0f, 20.0f};
2414 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2415 // Red background.
2416 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2417 redLayer.alpha = 1.0f;
2418
2419 layers.push_back(redLayer);
2420
2421 invokeDraw(settings, layers);
2422
2423 // Due to roundedCornersRadius, the corners are untouched.
2424 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2425 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2426 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2427 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2428
2429 // Y-axis draws a larger radius, check that its untouched as well
2430 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 5), 0, 0, 0, 0);
2431 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 5), 0, 0, 0, 0);
2432 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 5), 0, 0, 0, 0);
2433 expectBufferColor(Point(0, 5), 0, 0, 0, 0);
2434
2435 // middle should be red
2436 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0, 255);
2437}
2438
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002439TEST_P(RenderEngineTest, testClear) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002440 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002441 GTEST_SKIP();
2442 }
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002443 initializeRenderEngine();
2444
2445 const auto rect = fullscreenRect();
2446 const renderengine::DisplaySettings display{
2447 .physicalDisplay = rect,
2448 .clip = rect,
2449 };
2450
2451 const renderengine::LayerSettings redLayer{
2452 .geometry.boundaries = rect.toFloatRect(),
2453 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
2454 .alpha = 1.0f,
2455 };
2456
2457 // This mimics prepareClearClientComposition. This layer should overwrite
2458 // the redLayer, so that the buffer is transparent, rather than red.
2459 const renderengine::LayerSettings clearLayer{
2460 .geometry.boundaries = rect.toFloatRect(),
2461 .source.solidColor = half3(0.0f, 0.0f, 0.0f),
2462 .alpha = 0.0f,
2463 .disableBlending = true,
2464 };
2465
Sally Qi59a9f502021-10-12 18:53:23 +00002466 std::vector<renderengine::LayerSettings> layers{redLayer, clearLayer};
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002467 invokeDraw(display, layers);
2468 expectBufferColor(rect, 0, 0, 0, 0);
2469}
2470
2471TEST_P(RenderEngineTest, testDisableBlendingBuffer) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002472 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002473 GTEST_SKIP();
2474 }
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002475 initializeRenderEngine();
2476
2477 const auto rect = Rect(0, 0, 1, 1);
2478 const renderengine::DisplaySettings display{
2479 .physicalDisplay = rect,
2480 .clip = rect,
2481 };
2482
2483 const renderengine::LayerSettings redLayer{
2484 .geometry.boundaries = rect.toFloatRect(),
2485 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
2486 .alpha = 1.0f,
2487 };
2488
2489 // The next layer will overwrite redLayer with a GraphicBuffer that is green
2490 // applied with a translucent alpha.
Alec Mouria90a5702021-04-16 16:36:21 +00002491 const auto buf = allocateSourceBuffer(1, 1);
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002492 {
2493 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00002494 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2495 reinterpret_cast<void**>(&pixels));
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002496 pixels[0] = 0;
2497 pixels[1] = 255;
2498 pixels[2] = 0;
2499 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00002500 buf->getBuffer()->unlock();
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002501 }
2502
2503 const renderengine::LayerSettings greenLayer{
2504 .geometry.boundaries = rect.toFloatRect(),
2505 .source =
2506 renderengine::PixelSource{
2507 .buffer =
2508 renderengine::Buffer{
2509 .buffer = buf,
2510 .usePremultipliedAlpha = true,
2511 },
2512 },
2513 .alpha = 0.5f,
2514 .disableBlending = true,
2515 };
2516
Sally Qi59a9f502021-10-12 18:53:23 +00002517 std::vector<renderengine::LayerSettings> layers{redLayer, greenLayer};
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002518 invokeDraw(display, layers);
2519 expectBufferColor(rect, 0, 128, 0, 128);
2520}
2521
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002522TEST_P(RenderEngineTest, testDimming) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002523 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002524 GTEST_SKIP();
2525 }
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002526 initializeRenderEngine();
2527
Alec Mouri85065692022-03-18 00:58:26 +00002528 const ui::Dataspace dataspace = ui::Dataspace::V0_SRGB_LINEAR;
2529
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002530 const auto displayRect = Rect(3, 1);
2531 const renderengine::DisplaySettings display{
2532 .physicalDisplay = displayRect,
2533 .clip = displayRect,
Alec Mouri85065692022-03-18 00:58:26 +00002534 .outputDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002535 .targetLuminanceNits = 1000.f,
2536 };
2537
2538 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2539 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2540 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2541
2542 const renderengine::LayerSettings greenLayer{
2543 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2544 .source =
2545 renderengine::PixelSource{
2546 .buffer =
2547 renderengine::Buffer{
2548 .buffer = greenBuffer,
2549 .usePremultipliedAlpha = true,
2550 },
2551 },
2552 .alpha = 1.0f,
Alec Mouri85065692022-03-18 00:58:26 +00002553 .sourceDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002554 .whitePointNits = 200.f,
2555 };
2556
2557 const renderengine::LayerSettings blueLayer{
2558 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2559 .source =
2560 renderengine::PixelSource{
2561 .buffer =
2562 renderengine::Buffer{
2563 .buffer = blueBuffer,
2564 .usePremultipliedAlpha = true,
2565 },
2566 },
2567 .alpha = 1.0f,
Alec Mouri85065692022-03-18 00:58:26 +00002568 .sourceDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002569 .whitePointNits = 1000.f / 51.f,
2570 };
2571
2572 const renderengine::LayerSettings redLayer{
2573 .geometry.boundaries = FloatRect(2.f, 0.f, 3.f, 1.f),
2574 .source =
2575 renderengine::PixelSource{
2576 .buffer =
2577 renderengine::Buffer{
2578 .buffer = redBuffer,
2579 .usePremultipliedAlpha = true,
2580 },
2581 },
2582 .alpha = 1.0f,
Alec Mouri85065692022-03-18 00:58:26 +00002583 .sourceDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002584 // When the white point is not set for a layer, just ignore it and treat it as the same
2585 // as the max layer
2586 .whitePointNits = -1.f,
2587 };
2588
2589 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer, redLayer};
2590 invokeDraw(display, layers);
2591
2592 expectBufferColor(Rect(1, 1), 0, 51, 0, 255, 1);
2593 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 5, 255, 1);
2594 expectBufferColor(Rect(2, 0, 3, 1), 51, 0, 0, 255, 1);
2595}
2596
Alec Mouri85065692022-03-18 00:58:26 +00002597TEST_P(RenderEngineTest, testDimming_inGammaSpace) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002598 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002599 GTEST_SKIP();
2600 }
Alec Mouri85065692022-03-18 00:58:26 +00002601 initializeRenderEngine();
2602
2603 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2604 ui::Dataspace::TRANSFER_GAMMA2_2 |
2605 ui::Dataspace::RANGE_FULL);
2606
2607 const auto displayRect = Rect(3, 1);
2608 const renderengine::DisplaySettings display{
2609 .physicalDisplay = displayRect,
2610 .clip = displayRect,
2611 .outputDataspace = dataspace,
2612 .targetLuminanceNits = 1000.f,
2613 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2614 };
2615
2616 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2617 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2618 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2619
2620 const renderengine::LayerSettings greenLayer{
2621 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2622 .source =
2623 renderengine::PixelSource{
2624 .buffer =
2625 renderengine::Buffer{
2626 .buffer = greenBuffer,
2627 .usePremultipliedAlpha = true,
2628 },
2629 },
2630 .alpha = 1.0f,
2631 .sourceDataspace = dataspace,
2632 .whitePointNits = 200.f,
2633 };
2634
2635 const renderengine::LayerSettings blueLayer{
2636 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2637 .source =
2638 renderengine::PixelSource{
2639 .buffer =
2640 renderengine::Buffer{
2641 .buffer = blueBuffer,
2642 .usePremultipliedAlpha = true,
2643 },
2644 },
2645 .alpha = 1.0f,
2646 .sourceDataspace = dataspace,
2647 .whitePointNits = 1000.f / 51.f,
2648 };
2649
2650 const renderengine::LayerSettings redLayer{
2651 .geometry.boundaries = FloatRect(2.f, 0.f, 3.f, 1.f),
2652 .source =
2653 renderengine::PixelSource{
2654 .buffer =
2655 renderengine::Buffer{
2656 .buffer = redBuffer,
2657 .usePremultipliedAlpha = true,
2658 },
2659 },
2660 .alpha = 1.0f,
2661 .sourceDataspace = dataspace,
2662 // When the white point is not set for a layer, just ignore it and treat it as the same
2663 // as the max layer
2664 .whitePointNits = -1.f,
2665 };
2666
2667 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer, redLayer};
2668 invokeDraw(display, layers);
2669
2670 expectBufferColor(Rect(1, 1), 0, 122, 0, 255, 1);
2671 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 42, 255, 1);
2672 expectBufferColor(Rect(2, 0, 3, 1), 122, 0, 0, 255, 1);
2673}
2674
Alec Mouri9bcd1d12022-04-21 22:16:56 +00002675TEST_P(RenderEngineTest, testDimming_inGammaSpace_withDisplayColorTransform) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002676 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002677 GTEST_SKIP();
2678 }
Alec Mouri9bcd1d12022-04-21 22:16:56 +00002679 initializeRenderEngine();
2680
2681 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2682 ui::Dataspace::TRANSFER_GAMMA2_2 |
2683 ui::Dataspace::RANGE_FULL);
2684
2685 const auto displayRect = Rect(3, 1);
2686 const renderengine::DisplaySettings display{
2687 .physicalDisplay = displayRect,
2688 .clip = displayRect,
2689 .outputDataspace = dataspace,
2690 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
2691 .targetLuminanceNits = 1000.f,
2692 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2693 };
2694
2695 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2696 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2697 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2698
2699 const renderengine::LayerSettings greenLayer{
2700 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2701 .source =
2702 renderengine::PixelSource{
2703 .buffer =
2704 renderengine::Buffer{
2705 .buffer = greenBuffer,
2706 .usePremultipliedAlpha = true,
2707 },
2708 },
2709 .alpha = 1.0f,
2710 .sourceDataspace = dataspace,
2711 .whitePointNits = 200.f,
2712 };
2713
2714 const renderengine::LayerSettings redLayer{
2715 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2716 .source =
2717 renderengine::PixelSource{
2718 .buffer =
2719 renderengine::Buffer{
2720 .buffer = redBuffer,
2721 .usePremultipliedAlpha = true,
2722 },
2723 },
2724 .alpha = 1.0f,
2725 .sourceDataspace = dataspace,
2726 // When the white point is not set for a layer, just ignore it and treat it as the same
2727 // as the max layer
2728 .whitePointNits = -1.f,
2729 };
2730
2731 std::vector<renderengine::LayerSettings> layers{greenLayer, redLayer};
2732 invokeDraw(display, layers);
2733
2734 expectBufferColor(Rect(1, 1), 0, 0, 0, 255, 1);
2735 expectBufferColor(Rect(1, 0, 2, 1), 0, 122, 0, 255, 1);
2736}
2737
2738TEST_P(RenderEngineTest, testDimming_inGammaSpace_withDisplayColorTransform_deviceHandles) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002739 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002740 GTEST_SKIP();
2741 }
Alec Mouri9bcd1d12022-04-21 22:16:56 +00002742 initializeRenderEngine();
2743
2744 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2745 ui::Dataspace::TRANSFER_GAMMA2_2 |
2746 ui::Dataspace::RANGE_FULL);
2747
2748 const auto displayRect = Rect(3, 1);
2749 const renderengine::DisplaySettings display{
2750 .physicalDisplay = displayRect,
2751 .clip = displayRect,
2752 .outputDataspace = dataspace,
2753 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
2754 .deviceHandlesColorTransform = true,
2755 .targetLuminanceNits = 1000.f,
2756 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2757 };
2758
2759 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2760 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2761 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2762
2763 const renderengine::LayerSettings greenLayer{
2764 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2765 .source =
2766 renderengine::PixelSource{
2767 .buffer =
2768 renderengine::Buffer{
2769 .buffer = greenBuffer,
2770 .usePremultipliedAlpha = true,
2771 },
2772 },
2773 .alpha = 1.0f,
2774 .sourceDataspace = dataspace,
2775 .whitePointNits = 200.f,
2776 };
2777
2778 const renderengine::LayerSettings redLayer{
2779 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2780 .source =
2781 renderengine::PixelSource{
2782 .buffer =
2783 renderengine::Buffer{
2784 .buffer = redBuffer,
2785 .usePremultipliedAlpha = true,
2786 },
2787 },
2788 .alpha = 1.0f,
2789 .sourceDataspace = dataspace,
2790 // When the white point is not set for a layer, just ignore it and treat it as the same
2791 // as the max layer
2792 .whitePointNits = -1.f,
2793 };
2794
2795 std::vector<renderengine::LayerSettings> layers{greenLayer, redLayer};
2796 invokeDraw(display, layers);
2797
2798 expectBufferColor(Rect(1, 1), 0, 122, 0, 255, 1);
2799 expectBufferColor(Rect(1, 0, 2, 1), 122, 0, 0, 255, 1);
2800}
2801
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002802TEST_P(RenderEngineTest, testDimming_withoutTargetLuminance) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002803 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002804 GTEST_SKIP();
2805 }
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002806 initializeRenderEngine();
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002807
2808 const auto displayRect = Rect(2, 1);
2809 const renderengine::DisplaySettings display{
2810 .physicalDisplay = displayRect,
2811 .clip = displayRect,
2812 .outputDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2813 .targetLuminanceNits = -1.f,
2814 };
2815
2816 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2817 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2818
2819 const renderengine::LayerSettings greenLayer{
2820 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2821 .source =
2822 renderengine::PixelSource{
2823 .buffer =
2824 renderengine::Buffer{
2825 .buffer = greenBuffer,
2826 .usePremultipliedAlpha = true,
2827 },
2828 },
2829 .alpha = 1.0f,
2830 .sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2831 .whitePointNits = 200.f,
2832 };
2833
2834 const renderengine::LayerSettings blueLayer{
2835 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2836 .source =
2837 renderengine::PixelSource{
2838 .buffer =
2839 renderengine::Buffer{
2840 .buffer = blueBuffer,
2841 .usePremultipliedAlpha = true,
2842 },
2843 },
2844 .alpha = 1.0f,
2845 .sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2846 .whitePointNits = 1000.f,
2847 };
2848
2849 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer};
2850 invokeDraw(display, layers);
2851
2852 expectBufferColor(Rect(1, 1), 0, 51, 0, 255, 1);
2853 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 255, 255);
2854}
2855
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002856TEST_P(RenderEngineTest, test_isOpaque) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002857 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002858 GTEST_SKIP();
2859 }
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002860 initializeRenderEngine();
2861
2862 const auto rect = Rect(0, 0, 1, 1);
2863 const renderengine::DisplaySettings display{
2864 .physicalDisplay = rect,
2865 .clip = rect,
2866 .outputDataspace = ui::Dataspace::DISPLAY_P3,
2867 };
2868
2869 // Create an unpremul buffer that is green with no alpha. Using isOpaque
2870 // should make the green show.
2871 const auto buf = allocateSourceBuffer(1, 1);
2872 {
2873 uint8_t* pixels;
2874 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2875 reinterpret_cast<void**>(&pixels));
2876 pixels[0] = 0;
2877 pixels[1] = 255;
2878 pixels[2] = 0;
2879 pixels[3] = 0;
2880 buf->getBuffer()->unlock();
2881 }
2882
2883 const renderengine::LayerSettings greenLayer{
2884 .geometry.boundaries = rect.toFloatRect(),
2885 .source =
2886 renderengine::PixelSource{
2887 .buffer =
2888 renderengine::Buffer{
2889 .buffer = buf,
2890 // Although the pixels are not
2891 // premultiplied in practice, this
2892 // matches the input we see.
2893 .usePremultipliedAlpha = true,
2894 .isOpaque = true,
2895 },
2896 },
2897 .alpha = 1.0f,
2898 };
2899
Sally Qi59a9f502021-10-12 18:53:23 +00002900 std::vector<renderengine::LayerSettings> layers{greenLayer};
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002901 invokeDraw(display, layers);
2902
Alec Mouri47bcb072023-08-15 02:02:49 +00002903 expectBufferColor(rect, 117, 251, 76, 255);
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002904}
Alec Mouri4049b532021-10-15 20:59:33 -07002905
Alec Mouri4049b532021-10-15 20:59:33 -07002906TEST_P(RenderEngineTest, test_tonemapPQMatches) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002907 if (!GetParam()->apiSupported()) {
Alec Mouri5a493722022-01-26 16:43:02 -08002908 GTEST_SKIP();
Alec Mouri4049b532021-10-15 20:59:33 -07002909 }
2910
Alec Mouri4049b532021-10-15 20:59:33 -07002911 initializeRenderEngine();
2912
Alec Mouri5a493722022-01-26 16:43:02 -08002913 tonemap(
2914 static_cast<ui::Dataspace>(HAL_DATASPACE_STANDARD_BT2020 |
2915 HAL_DATASPACE_TRANSFER_ST2084 | HAL_DATASPACE_RANGE_FULL),
2916 [](vec3 color) { return EOTF_PQ(color); },
2917 [](vec3 color, float) {
2918 static constexpr float kMaxPQLuminance = 10000.f;
2919 return color * kMaxPQLuminance;
2920 });
2921}
Alec Mouri4049b532021-10-15 20:59:33 -07002922
Alec Mouri5a493722022-01-26 16:43:02 -08002923TEST_P(RenderEngineTest, test_tonemapHLGMatches) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002924 if (!GetParam()->apiSupported()) {
Alec Mouri5a493722022-01-26 16:43:02 -08002925 GTEST_SKIP();
Alec Mouri4049b532021-10-15 20:59:33 -07002926 }
2927
Alec Mouri5a493722022-01-26 16:43:02 -08002928 initializeRenderEngine();
Alec Mouri4049b532021-10-15 20:59:33 -07002929
Alec Mouri5a493722022-01-26 16:43:02 -08002930 tonemap(
2931 static_cast<ui::Dataspace>(HAL_DATASPACE_STANDARD_BT2020 | HAL_DATASPACE_TRANSFER_HLG |
2932 HAL_DATASPACE_RANGE_FULL),
2933 [](vec3 color) { return EOTF_HLG(color); },
2934 [](vec3 color, float currentLuminaceNits) {
2935 static constexpr float kMaxHLGLuminance = 1000.f;
Alec Mouri7a577452022-03-04 23:41:38 +00002936 return color * kMaxHLGLuminance;
Alec Mouri5a493722022-01-26 16:43:02 -08002937 });
Alec Mouri4049b532021-10-15 20:59:33 -07002938}
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -05002939
2940TEST_P(RenderEngineTest, r8_behaves_as_mask) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002941 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002942 GTEST_SKIP();
2943 }
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -05002944 initializeRenderEngine();
2945
2946 const auto r8Buffer = allocateR8Buffer(2, 1);
2947 if (!r8Buffer) {
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05002948 GTEST_SKIP() << "Test is only necessary on devices that support r8";
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -05002949 return;
2950 }
2951 {
2952 uint8_t* pixels;
2953 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2954 reinterpret_cast<void**>(&pixels));
2955 // This will be drawn on top of a green buffer. We'll verify that 255
2956 // results in keeping the original green and 0 results in black.
2957 pixels[0] = 0;
2958 pixels[1] = 255;
2959 r8Buffer->getBuffer()->unlock();
2960 }
2961
2962 const auto rect = Rect(0, 0, 2, 1);
2963 const renderengine::DisplaySettings display{
2964 .physicalDisplay = rect,
2965 .clip = rect,
2966 .outputDataspace = ui::Dataspace::SRGB,
2967 };
2968
2969 const auto greenBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(0, 255, 0, 255));
2970 const renderengine::LayerSettings greenLayer{
2971 .geometry.boundaries = rect.toFloatRect(),
2972 .source =
2973 renderengine::PixelSource{
2974 .buffer =
2975 renderengine::Buffer{
2976 .buffer = greenBuffer,
2977 },
2978 },
2979 .alpha = 1.0f,
2980 };
2981 const renderengine::LayerSettings r8Layer{
2982 .geometry.boundaries = rect.toFloatRect(),
2983 .source =
2984 renderengine::PixelSource{
2985 .buffer =
2986 renderengine::Buffer{
2987 .buffer = r8Buffer,
2988 },
2989 },
2990 .alpha = 1.0f,
2991 };
2992
2993 std::vector<renderengine::LayerSettings> layers{greenLayer, r8Layer};
2994 invokeDraw(display, layers);
2995
2996 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 255);
2997 expectBufferColor(Rect(1, 0, 2, 1), 0, 255, 0, 255);
2998}
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05002999
3000TEST_P(RenderEngineTest, r8_respects_color_transform) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05003001 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003002 GTEST_SKIP();
3003 }
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003004 initializeRenderEngine();
3005
3006 const auto r8Buffer = allocateR8Buffer(2, 1);
3007 if (!r8Buffer) {
3008 GTEST_SKIP() << "Test is only necessary on devices that support r8";
3009 return;
3010 }
3011 {
3012 uint8_t* pixels;
3013 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
3014 reinterpret_cast<void**>(&pixels));
3015 pixels[0] = 0;
3016 pixels[1] = 255;
3017 r8Buffer->getBuffer()->unlock();
3018 }
3019
3020 const auto rect = Rect(0, 0, 2, 1);
3021 const renderengine::DisplaySettings display{
3022 .physicalDisplay = rect,
3023 .clip = rect,
3024 .outputDataspace = ui::Dataspace::SRGB,
3025 // Verify that the R8 layer respects the color transform when
3026 // deviceHandlesColorTransform is false. This transform converts
3027 // pure red to pure green. That will occur when the R8 buffer is
3028 // 255. When the R8 buffer is 0, it will still change to black, as
3029 // with r8_behaves_as_mask.
Alec Mouri9bcd1d12022-04-21 22:16:56 +00003030 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003031 .deviceHandlesColorTransform = false,
3032 };
3033
3034 const auto redBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(255, 0, 0, 255));
3035 const renderengine::LayerSettings redLayer{
3036 .geometry.boundaries = rect.toFloatRect(),
3037 .source =
3038 renderengine::PixelSource{
3039 .buffer =
3040 renderengine::Buffer{
3041 .buffer = redBuffer,
3042 },
3043 },
3044 .alpha = 1.0f,
3045 };
3046 const renderengine::LayerSettings r8Layer{
3047 .geometry.boundaries = rect.toFloatRect(),
3048 .source =
3049 renderengine::PixelSource{
3050 .buffer =
3051 renderengine::Buffer{
3052 .buffer = r8Buffer,
3053 },
3054 },
3055 .alpha = 1.0f,
3056 };
3057
3058 std::vector<renderengine::LayerSettings> layers{redLayer, r8Layer};
3059 invokeDraw(display, layers);
3060
3061 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 255);
3062 expectBufferColor(Rect(1, 0, 2, 1), 0, 255, 0, 255);
3063}
3064
3065TEST_P(RenderEngineTest, r8_respects_color_transform_when_device_handles) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05003066 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003067 GTEST_SKIP();
3068 }
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003069 initializeRenderEngine();
3070
3071 const auto r8Buffer = allocateR8Buffer(2, 1);
3072 if (!r8Buffer) {
3073 GTEST_SKIP() << "Test is only necessary on devices that support r8";
3074 return;
3075 }
3076 {
3077 uint8_t* pixels;
3078 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
3079 reinterpret_cast<void**>(&pixels));
3080 pixels[0] = 0;
3081 pixels[1] = 255;
3082 r8Buffer->getBuffer()->unlock();
3083 }
3084
3085 const auto rect = Rect(0, 0, 2, 1);
3086 const renderengine::DisplaySettings display{
3087 .physicalDisplay = rect,
3088 .clip = rect,
3089 .outputDataspace = ui::Dataspace::SRGB,
3090 // If deviceHandlesColorTransform is true, pixels where the A8
3091 // buffer is opaque are unaffected. If the colorTransform is
3092 // invertible, pixels where the A8 buffer are transparent have the
3093 // inverse applied to them so that the DPU will convert them back to
3094 // black. Test with an arbitrary, invertible matrix.
3095 .colorTransform = mat4(1, 0, 0, 2,
3096 3, 1, 2, 5,
3097 0, 5, 3, 0,
3098 0, 1, 0, 2),
3099 .deviceHandlesColorTransform = true,
3100 };
3101
3102 const auto redBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(255, 0, 0, 255));
3103 const renderengine::LayerSettings redLayer{
3104 .geometry.boundaries = rect.toFloatRect(),
3105 .source =
3106 renderengine::PixelSource{
3107 .buffer =
3108 renderengine::Buffer{
3109 .buffer = redBuffer,
3110 },
3111 },
3112 .alpha = 1.0f,
3113 };
3114 const renderengine::LayerSettings r8Layer{
3115 .geometry.boundaries = rect.toFloatRect(),
3116 .source =
3117 renderengine::PixelSource{
3118 .buffer =
3119 renderengine::Buffer{
3120 .buffer = r8Buffer,
3121 },
3122 },
3123 .alpha = 1.0f,
3124 };
3125
3126 std::vector<renderengine::LayerSettings> layers{redLayer, r8Layer};
3127 invokeDraw(display, layers);
3128
3129 expectBufferColor(Rect(1, 0, 2, 1), 255, 0, 0, 255); // Still red.
3130 expectBufferColor(Rect(0, 0, 1, 1), 0, 70, 0, 255);
3131}
Leon Scroggins III45be9182022-04-27 10:37:11 -04003132
3133TEST_P(RenderEngineTest, primeShaderCache) {
Nolan Scobie195631a2024-03-26 12:22:23 -04003134 // TODO: b/331447071 - Fix in Graphite and re-enable.
3135 if (GetParam()->skiaBackend() == renderengine::RenderEngine::SkiaBackend::GRAPHITE) {
3136 GTEST_SKIP();
3137 }
3138
Leon Scroggins III696bf932024-01-24 15:21:05 -05003139 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003140 GTEST_SKIP();
3141 }
Leon Scroggins III45be9182022-04-27 10:37:11 -04003142 initializeRenderEngine();
3143
Bruno BELANYIb9b5b702023-10-13 13:25:11 +00003144 auto fut = mRE->primeCache(false);
Leon Scroggins III45be9182022-04-27 10:37:11 -04003145 if (fut.valid()) {
3146 fut.wait();
3147 }
3148
Alec Mouri47bcb072023-08-15 02:02:49 +00003149 static constexpr int kMinimumExpectedShadersCompiled = 60;
Leon Scroggins III45be9182022-04-27 10:37:11 -04003150 ASSERT_GT(static_cast<skia::SkiaGLRenderEngine*>(mRE.get())->reportShadersCompiled(),
Alec Mouri47bcb072023-08-15 02:02:49 +00003151 kMinimumExpectedShadersCompiled);
Leon Scroggins III45be9182022-04-27 10:37:11 -04003152}
Derek Sollenbergerd3f60652021-06-11 15:34:36 -04003153} // namespace renderengine
Alec Mouri6e57f682018-09-29 20:45:08 -07003154} // namespace android
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08003155
3156// TODO(b/129481165): remove the #pragma below and fix conversion issues
Marin Shalamanovbed7fd32020-12-21 20:02:20 +01003157#pragma clang diagnostic pop // ignored "-Wconversion -Wextra"