blob: a8a98236e2129765bf68639cae7ca8a108a62597 [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
Nolan Scobie488101b2024-05-20 13:32:13 -040025#include <com_android_graphics_surfaceflinger_flags.h>
Lucas Dupin19c8f0e2019-11-25 17:55:44 -080026#include <cutils/properties.h>
Ana Krulec9bc9dc62020-02-26 12:16:40 -080027#include <gtest/gtest.h>
Alec Mouria90a5702021-04-16 16:36:21 +000028#include <renderengine/ExternalTexture.h>
Alec Mouri6e57f682018-09-29 20:45:08 -070029#include <renderengine/RenderEngine.h>
Vishnu Nairdbbe3852022-01-12 20:22:11 -080030#include <renderengine/impl/ExternalTexture.h>
Alec Mouri1089aed2018-10-25 21:33:57 -070031#include <sync/sync.h>
Alec Mouri4049b532021-10-15 20:59:33 -070032#include <system/graphics-base-v1.0.h>
33#include <tonemap/tonemap.h>
34#include <ui/ColorSpace.h>
Alec Mouri6e57f682018-09-29 20:45:08 -070035#include <ui/PixelFormat.h>
Alec Mouric0aae732021-01-12 13:32:18 -080036
37#include <chrono>
38#include <condition_variable>
39#include <fstream>
40
Alec Mouric0aae732021-01-12 13:32:18 -080041#include "../skia/SkiaGLRenderEngine.h"
Ian Elliott1f0911e2022-09-09 16:31:47 -060042#include "../skia/SkiaVkRenderEngine.h"
Ana Krulec9bc9dc62020-02-26 12:16:40 -080043#include "../threaded/RenderEngineThreaded.h"
Alec Mouri6e57f682018-09-29 20:45:08 -070044
Nolan Scobie488101b2024-05-20 13:32:13 -040045// TODO: b/341728634 - Clean up conditional compilation.
46#if COM_ANDROID_GRAPHICS_SURFACEFLINGER_FLAGS(GRAPHITE_RENDERENGINE) || \
47 COM_ANDROID_GRAPHICS_SURFACEFLINGER_FLAGS(FORCE_COMPILE_GRAPHITE_RENDERENGINE)
48#define COMPILE_GRAPHITE_RENDERENGINE 1
49#else
50#define COMPILE_GRAPHITE_RENDERENGINE 0
51#endif
52
Alec Mouri1089aed2018-10-25 21:33:57 -070053constexpr int DEFAULT_DISPLAY_WIDTH = 128;
54constexpr int DEFAULT_DISPLAY_HEIGHT = 256;
55constexpr int DEFAULT_DISPLAY_OFFSET = 64;
Vishnu Nair16efdbf2019-12-10 11:55:42 -080056constexpr bool WRITE_BUFFER_TO_FILE_ON_FAILURE = false;
Alec Mouri1089aed2018-10-25 21:33:57 -070057
Alec Mouri6e57f682018-09-29 20:45:08 -070058namespace android {
Derek Sollenbergerd3f60652021-06-11 15:34:36 -040059namespace renderengine {
Alec Mouri6e57f682018-09-29 20:45:08 -070060
Alec Mouri5a493722022-01-26 16:43:02 -080061namespace {
62
63double EOTF_PQ(double channel) {
64 float m1 = (2610.0 / 4096.0) / 4.0;
65 float m2 = (2523.0 / 4096.0) * 128.0;
66 float c1 = (3424.0 / 4096.0);
67 float c2 = (2413.0 / 4096.0) * 32.0;
68 float c3 = (2392.0 / 4096.0) * 32.0;
69
70 float tmp = std::pow(std::clamp(channel, 0.0, 1.0), 1.0 / m2);
71 tmp = std::fmax(tmp - c1, 0.0) / (c2 - c3 * tmp);
72 return std::pow(tmp, 1.0 / m1);
73}
74
75vec3 EOTF_PQ(vec3 color) {
76 return vec3(EOTF_PQ(color.r), EOTF_PQ(color.g), EOTF_PQ(color.b));
77}
78
79double EOTF_HLG(double channel) {
80 const float a = 0.17883277;
81 const float b = 0.28466892;
82 const float c = 0.55991073;
83 return channel <= 0.5 ? channel * channel / 3.0 : (exp((channel - c) / a) + b) / 12.0;
84}
85
86vec3 EOTF_HLG(vec3 color) {
87 return vec3(EOTF_HLG(color.r), EOTF_HLG(color.g), EOTF_HLG(color.b));
88}
89
90double OETF_sRGB(double channel) {
91 return channel <= 0.0031308 ? channel * 12.92 : (pow(channel, 1.0 / 2.4) * 1.055) - 0.055;
92}
93
94int sign(float in) {
95 return in >= 0.0 ? 1 : -1;
96}
97
98vec3 OETF_sRGB(vec3 linear) {
99 return vec3(sign(linear.r) * OETF_sRGB(linear.r), sign(linear.g) * OETF_sRGB(linear.g),
100 sign(linear.b) * OETF_sRGB(linear.b));
101}
102
Alec Mouri9bcd1d12022-04-21 22:16:56 +0000103// clang-format off
104// Converts red channels to green channels, and zeroes out an existing green channel.
105static const auto kRemoveGreenAndMoveRedToGreenMat4 = mat4(0, 1, 0, 0,
106 0, 0, 0, 0,
107 0, 0, 1, 0,
108 0, 0, 0, 1);
109// clang-format on
110
Alec Mouri5a493722022-01-26 16:43:02 -0800111} // namespace
112
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800113class RenderEngineFactory {
114public:
115 virtual ~RenderEngineFactory() = default;
116
117 virtual std::string name() = 0;
Leon Scroggins III696bf932024-01-24 15:21:05 -0500118 virtual renderengine::RenderEngine::GraphicsApi graphicsApi() = 0;
Nolan Scobie195631a2024-03-26 12:22:23 -0400119 virtual renderengine::RenderEngine::SkiaBackend skiaBackend() = 0;
Leon Scroggins IIIf3369ed2024-02-16 17:52:42 -0500120 bool apiSupported() { return renderengine::RenderEngine::canSupport(graphicsApi()); }
Leon Scroggins III5ef55002024-01-25 10:51:45 -0500121 std::unique_ptr<renderengine::RenderEngine> createRenderEngine() {
122 renderengine::RenderEngineCreationArgs reCreationArgs =
123 renderengine::RenderEngineCreationArgs::Builder()
124 .setPixelFormat(static_cast<int>(ui::PixelFormat::RGBA_8888))
125 .setImageCacheSize(1)
126 .setEnableProtectedContext(false)
127 .setPrecacheToneMapperShaderOnly(false)
Robin Lee7338bd92024-04-04 14:05:07 +0000128 .setBlurAlgorithm(renderengine::RenderEngine::BlurAlgorithm::KAWASE)
Leon Scroggins III5ef55002024-01-25 10:51:45 -0500129 .setContextPriority(renderengine::RenderEngine::ContextPriority::MEDIUM)
Leon Scroggins III696bf932024-01-24 15:21:05 -0500130 .setThreaded(renderengine::RenderEngine::Threaded::NO)
131 .setGraphicsApi(graphicsApi())
Nolan Scobie195631a2024-03-26 12:22:23 -0400132 .setSkiaBackend(skiaBackend())
Leon Scroggins III5ef55002024-01-25 10:51:45 -0500133 .build();
134 return renderengine::RenderEngine::create(reCreationArgs);
135 }
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800136};
137
Alec Mouri0eab3e82020-12-08 18:10:27 -0800138class SkiaGLESRenderEngineFactory : public RenderEngineFactory {
139public:
Alec Mouric0aae732021-01-12 13:32:18 -0800140 std::string name() override { return "SkiaGLRenderEngineFactory"; }
Alec Mouri0eab3e82020-12-08 18:10:27 -0800141
Leon Scroggins III696bf932024-01-24 15:21:05 -0500142 renderengine::RenderEngine::GraphicsApi graphicsApi() {
143 return renderengine::RenderEngine::GraphicsApi::GL;
Alec Mouric0aae732021-01-12 13:32:18 -0800144 }
Nolan Scobie195631a2024-03-26 12:22:23 -0400145
146 renderengine::RenderEngine::SkiaBackend skiaBackend() override {
147 return renderengine::RenderEngine::SkiaBackend::GANESH;
148 }
149};
150
151class GaneshVkRenderEngineFactory : public RenderEngineFactory {
152public:
153 std::string name() override { return "GaneshVkRenderEngineFactory"; }
154
155 renderengine::RenderEngine::GraphicsApi graphicsApi() override {
156 return renderengine::RenderEngine::GraphicsApi::VK;
157 }
158
159 renderengine::RenderEngine::SkiaBackend skiaBackend() override {
160 return renderengine::RenderEngine::SkiaBackend::GANESH;
161 }
162};
163
Nolan Scobie488101b2024-05-20 13:32:13 -0400164// TODO: b/341728634 - Clean up conditional compilation.
165#if COMPILE_GRAPHITE_RENDERENGINE
Nolan Scobie195631a2024-03-26 12:22:23 -0400166class GraphiteVkRenderEngineFactory : public RenderEngineFactory {
167public:
168 std::string name() override { return "GraphiteVkRenderEngineFactory"; }
169
170 renderengine::RenderEngine::GraphicsApi graphicsApi() override {
171 return renderengine::RenderEngine::GraphicsApi::VK;
172 }
173
174 renderengine::RenderEngine::SkiaBackend skiaBackend() override {
175 return renderengine::RenderEngine::SkiaBackend::GRAPHITE;
176 }
Alec Mouri0eab3e82020-12-08 18:10:27 -0800177};
Nolan Scobie488101b2024-05-20 13:32:13 -0400178#endif
Alec Mouri0eab3e82020-12-08 18:10:27 -0800179
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800180class RenderEngineTest : public ::testing::TestWithParam<std::shared_ptr<RenderEngineFactory>> {
181public:
Alec Mouria90a5702021-04-16 16:36:21 +0000182 std::shared_ptr<renderengine::ExternalTexture> allocateDefaultBuffer() {
183 return std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800184 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -0700185 ExternalTexture>(sp<GraphicBuffer>::
186 make(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT,
187 HAL_PIXEL_FORMAT_RGBA_8888, 1,
188 GRALLOC_USAGE_SW_READ_OFTEN |
189 GRALLOC_USAGE_SW_WRITE_OFTEN |
190 GRALLOC_USAGE_HW_RENDER |
191 GRALLOC_USAGE_HW_TEXTURE,
192 "output"),
Alec Mouria90a5702021-04-16 16:36:21 +0000193 *mRE,
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800194 renderengine::impl::ExternalTexture::Usage::READABLE |
195 renderengine::impl::ExternalTexture::Usage::
196 WRITEABLE);
Alec Mouri6e57f682018-09-29 20:45:08 -0700197 }
198
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800199 // Allocates a 1x1 buffer to fill with a solid color
Alec Mouria90a5702021-04-16 16:36:21 +0000200 std::shared_ptr<renderengine::ExternalTexture> allocateSourceBuffer(uint32_t width,
201 uint32_t height) {
202 return std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800203 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -0700204 ExternalTexture>(sp<GraphicBuffer>::
205 make(width, height, HAL_PIXEL_FORMAT_RGBA_8888, 1,
206 GRALLOC_USAGE_SW_READ_OFTEN |
207 GRALLOC_USAGE_SW_WRITE_OFTEN |
208 GRALLOC_USAGE_HW_TEXTURE,
209 "input"),
Alec Mouria90a5702021-04-16 16:36:21 +0000210 *mRE,
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800211 renderengine::impl::ExternalTexture::Usage::READABLE |
212 renderengine::impl::ExternalTexture::Usage::
213 WRITEABLE);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800214 }
215
Alec Mouricdf6cbc2021-11-01 17:21:15 -0700216 std::shared_ptr<renderengine::ExternalTexture> allocateAndFillSourceBuffer(uint32_t width,
217 uint32_t height,
218 ubyte4 color) {
219 const auto buffer = allocateSourceBuffer(width, height);
220 uint8_t* pixels;
221 buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
222 reinterpret_cast<void**>(&pixels));
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -0500223 for (uint32_t j = 0; j < height; j++) {
224 uint8_t* dst = pixels + (buffer->getBuffer()->getStride() * j * 4);
225 for (uint32_t i = 0; i < width; i++) {
226 dst[0] = color.r;
227 dst[1] = color.g;
228 dst[2] = color.b;
229 dst[3] = color.a;
230 dst += 4;
231 }
232 }
Alec Mouricdf6cbc2021-11-01 17:21:15 -0700233 buffer->getBuffer()->unlock();
234 return buffer;
235 }
236
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -0500237 std::shared_ptr<renderengine::ExternalTexture> allocateR8Buffer(int width, int height) {
Ady Abrahamd11bade2022-08-01 16:18:03 -0700238 const auto kUsageFlags =
239 static_cast<uint64_t>(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
240 GRALLOC_USAGE_HW_TEXTURE);
241 auto buffer =
242 sp<GraphicBuffer>::make(static_cast<uint32_t>(width), static_cast<uint32_t>(height),
243 android::PIXEL_FORMAT_R_8, 1u, kUsageFlags, "r8");
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -0500244 if (buffer->initCheck() != 0) {
245 // Devices are not required to support R8.
246 return nullptr;
247 }
248 return std::make_shared<
249 renderengine::impl::ExternalTexture>(std::move(buffer), *mRE,
250 renderengine::impl::ExternalTexture::Usage::
251 READABLE);
252 }
253
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800254 RenderEngineTest() {
255 const ::testing::TestInfo* const test_info =
256 ::testing::UnitTest::GetInstance()->current_test_info();
Nolan Scobie24a69102024-04-16 18:57:35 +0000257 ALOGI("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800258 }
Alec Mouri1089aed2018-10-25 21:33:57 -0700259
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800260 ~RenderEngineTest() {
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800261 if (WRITE_BUFFER_TO_FILE_ON_FAILURE && ::testing::Test::HasFailure()) {
262 writeBufferToFile("/data/texture_out_");
263 }
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800264 const ::testing::TestInfo* const test_info =
265 ::testing::UnitTest::GetInstance()->current_test_info();
Nolan Scobie24a69102024-04-16 18:57:35 +0000266 ALOGI("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800267 }
268
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800269 void writeBufferToFile(const char* basename) {
270 std::string filename(basename);
271 filename.append(::testing::UnitTest::GetInstance()->current_test_info()->name());
272 filename.append(".ppm");
273 std::ofstream file(filename.c_str(), std::ios::binary);
274 if (!file.is_open()) {
275 ALOGE("Unable to open file: %s", filename.c_str());
276 ALOGE("You may need to do: \"adb shell setenforce 0\" to enable "
277 "surfaceflinger to write debug images");
278 return;
279 }
280
Alec Mouri1089aed2018-10-25 21:33:57 -0700281 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +0000282 mBuffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
283 reinterpret_cast<void**>(&pixels));
Alec Mouri1089aed2018-10-25 21:33:57 -0700284
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800285 file << "P6\n";
Alec Mouria90a5702021-04-16 16:36:21 +0000286 file << mBuffer->getBuffer()->getWidth() << "\n";
287 file << mBuffer->getBuffer()->getHeight() << "\n";
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800288 file << 255 << "\n";
289
Alec Mouria90a5702021-04-16 16:36:21 +0000290 std::vector<uint8_t> outBuffer(mBuffer->getBuffer()->getWidth() *
291 mBuffer->getBuffer()->getHeight() * 3);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800292 auto outPtr = reinterpret_cast<uint8_t*>(outBuffer.data());
293
Alec Mouria90a5702021-04-16 16:36:21 +0000294 for (int32_t j = 0; j < mBuffer->getBuffer()->getHeight(); j++) {
295 const uint8_t* src = pixels + (mBuffer->getBuffer()->getStride() * j) * 4;
296 for (int32_t i = 0; i < mBuffer->getBuffer()->getWidth(); i++) {
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800297 // Only copy R, G and B components
298 outPtr[0] = src[0];
299 outPtr[1] = src[1];
300 outPtr[2] = src[2];
301 outPtr += 3;
302
303 src += 4;
304 }
305 }
306 file.write(reinterpret_cast<char*>(outBuffer.data()), outBuffer.size());
Alec Mouria90a5702021-04-16 16:36:21 +0000307 mBuffer->getBuffer()->unlock();
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800308 }
309
310 void expectBufferColor(const Region& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
311 size_t c;
312 Rect const* rect = region.getArray(&c);
313 for (size_t i = 0; i < c; i++, rect++) {
314 expectBufferColor(*rect, r, g, b, a);
315 }
316 }
317
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -0400318 void expectBufferColor(const Point& point, uint8_t r, uint8_t g, uint8_t b, uint8_t a,
319 uint8_t tolerance = 0) {
320 expectBufferColor(Rect(point.x, point.y, point.x + 1, point.y + 1), r, g, b, a, tolerance);
321 }
322
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800323 void expectBufferColor(const Rect& rect, uint8_t r, uint8_t g, uint8_t b, uint8_t a,
324 uint8_t tolerance = 0) {
Alec Mouri4049b532021-10-15 20:59:33 -0700325 auto generator = [=](Point) { return ubyte4(r, g, b, a); };
326 expectBufferColor(rect, generator, tolerance);
327 }
328
329 using ColorGenerator = std::function<ubyte4(Point location)>;
330
331 void expectBufferColor(const Rect& rect, ColorGenerator generator, uint8_t tolerance = 0) {
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800332 auto colorCompare = [tolerance](const uint8_t* colorA, const uint8_t* colorB) {
333 auto colorBitCompare = [tolerance](uint8_t a, uint8_t b) {
334 uint8_t tmp = a >= b ? a - b : b - a;
335 return tmp <= tolerance;
336 };
337 return std::equal(colorA, colorA + 4, colorB, colorBitCompare);
Alec Mouri1089aed2018-10-25 21:33:57 -0700338 };
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800339
Alec Mouri4049b532021-10-15 20:59:33 -0700340 expectBufferColor(rect, generator, colorCompare);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800341 }
342
Alec Mouri4049b532021-10-15 20:59:33 -0700343 void expectBufferColor(const Rect& region, ColorGenerator generator,
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800344 std::function<bool(const uint8_t* a, const uint8_t* b)> colorCompare) {
345 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +0000346 mBuffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
347 reinterpret_cast<void**>(&pixels));
Alec Mouri1089aed2018-10-25 21:33:57 -0700348 int32_t maxFails = 10;
349 int32_t fails = 0;
350 for (int32_t j = 0; j < region.getHeight(); j++) {
Alec Mouria90a5702021-04-16 16:36:21 +0000351 const uint8_t* src = pixels +
352 (mBuffer->getBuffer()->getStride() * (region.top + j) + region.left) * 4;
Alec Mouri1089aed2018-10-25 21:33:57 -0700353 for (int32_t i = 0; i < region.getWidth(); i++) {
Alec Mouri4049b532021-10-15 20:59:33 -0700354 const auto location = Point(region.left + i, region.top + j);
355 const ubyte4 colors = generator(location);
356 const uint8_t expected[4] = {colors.r, colors.g, colors.b, colors.a};
357 bool colorMatches = colorCompare(src, expected);
358 EXPECT_TRUE(colorMatches)
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -0400359 << GetParam()->name().c_str() << ": "
Alec Mouri4049b532021-10-15 20:59:33 -0700360 << "pixel @ (" << location.x << ", " << location.y << "): "
361 << "expected (" << static_cast<uint32_t>(colors.r) << ", "
362 << static_cast<uint32_t>(colors.g) << ", "
363 << static_cast<uint32_t>(colors.b) << ", "
364 << static_cast<uint32_t>(colors.a) << "), "
Alec Mouri1089aed2018-10-25 21:33:57 -0700365 << "got (" << static_cast<uint32_t>(src[0]) << ", "
366 << static_cast<uint32_t>(src[1]) << ", " << static_cast<uint32_t>(src[2])
367 << ", " << static_cast<uint32_t>(src[3]) << ")";
368 src += 4;
Alec Mouri4049b532021-10-15 20:59:33 -0700369 if (!colorMatches && ++fails >= maxFails) {
Alec Mouri1089aed2018-10-25 21:33:57 -0700370 break;
371 }
372 }
373 if (fails >= maxFails) {
374 break;
375 }
376 }
Alec Mouria90a5702021-04-16 16:36:21 +0000377 mBuffer->getBuffer()->unlock();
Alec Mouri1089aed2018-10-25 21:33:57 -0700378 }
379
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800380 void expectAlpha(const Rect& rect, uint8_t a) {
Alec Mouri4049b532021-10-15 20:59:33 -0700381 auto generator = [=](Point) { return ubyte4(0, 0, 0, a); };
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800382 auto colorCompare = [](const uint8_t* colorA, const uint8_t* colorB) {
383 return colorA[3] == colorB[3];
384 };
Alec Mouri4049b532021-10-15 20:59:33 -0700385 expectBufferColor(rect, generator, colorCompare);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800386 }
387
388 void expectShadowColor(const renderengine::LayerSettings& castingLayer,
Vishnu Naird9e4f462023-10-06 04:05:45 +0000389 const ShadowSettings& shadow, const ubyte4& casterColor,
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800390 const ubyte4& backgroundColor) {
391 const Rect casterRect(castingLayer.geometry.boundaries);
392 Region casterRegion = Region(casterRect);
Vishnu Nair50c0afe2022-07-11 15:04:07 -0700393 const float casterCornerRadius = (castingLayer.geometry.roundedCornersRadius.x +
394 castingLayer.geometry.roundedCornersRadius.y) /
395 2.0;
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800396 if (casterCornerRadius > 0.0f) {
397 // ignore the corners if a corner radius is set
398 Rect cornerRect(casterCornerRadius, casterCornerRadius);
399 casterRegion.subtractSelf(cornerRect.offsetTo(casterRect.left, casterRect.top));
400 casterRegion.subtractSelf(
401 cornerRect.offsetTo(casterRect.right - casterCornerRadius, casterRect.top));
402 casterRegion.subtractSelf(
403 cornerRect.offsetTo(casterRect.left, casterRect.bottom - casterCornerRadius));
404 casterRegion.subtractSelf(cornerRect.offsetTo(casterRect.right - casterCornerRadius,
405 casterRect.bottom - casterCornerRadius));
406 }
407
408 const float shadowInset = shadow.length * -1.0f;
409 const Rect casterWithShadow =
410 Rect(casterRect).inset(shadowInset, shadowInset, shadowInset, shadowInset);
411 const Region shadowRegion = Region(casterWithShadow).subtractSelf(casterRect);
412 const Region backgroundRegion = Region(fullscreenRect()).subtractSelf(casterWithShadow);
413
414 // verify casting layer
415 expectBufferColor(casterRegion, casterColor.r, casterColor.g, casterColor.b, casterColor.a);
416
417 // verify shadows by testing just the alpha since its difficult to validate the shadow color
418 size_t c;
419 Rect const* r = shadowRegion.getArray(&c);
420 for (size_t i = 0; i < c; i++, r++) {
421 expectAlpha(*r, 255);
422 }
423
424 // verify background
425 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
426 backgroundColor.a);
427 }
428
Vishnu Naird9e4f462023-10-06 04:05:45 +0000429 void expectShadowColorWithoutCaster(const FloatRect& casterBounds, const ShadowSettings& shadow,
Alec Mouribd17b3b2020-12-17 11:08:30 -0800430 const ubyte4& backgroundColor) {
431 const float shadowInset = shadow.length * -1.0f;
432 const Rect casterRect(casterBounds);
433 const Rect shadowRect =
434 Rect(casterRect).inset(shadowInset, shadowInset, shadowInset, shadowInset);
435
436 const Region backgroundRegion =
437 Region(fullscreenRect()).subtractSelf(casterRect).subtractSelf(shadowRect);
438
439 expectAlpha(shadowRect, 255);
440 // (0, 0, 0) fill on the bounds of the layer should be ignored.
441 expectBufferColor(casterRect, 255, 255, 255, 255, 254);
442
443 // verify background
444 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
445 backgroundColor.a);
446 }
447
Vishnu Naird9e4f462023-10-06 04:05:45 +0000448 static ShadowSettings getShadowSettings(const vec2& casterPos, float shadowLength,
449 bool casterIsTranslucent) {
450 ShadowSettings shadow;
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800451 shadow.ambientColor = {0.0f, 0.0f, 0.0f, 0.039f};
452 shadow.spotColor = {0.0f, 0.0f, 0.0f, 0.19f};
453 shadow.lightPos = vec3(casterPos.x, casterPos.y, 0);
454 shadow.lightRadius = 0.0f;
455 shadow.length = shadowLength;
456 shadow.casterIsTranslucent = casterIsTranslucent;
457 return shadow;
458 }
459
Alec Mouri1089aed2018-10-25 21:33:57 -0700460 static Rect fullscreenRect() { return Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT); }
461
462 static Rect offsetRect() {
463 return Rect(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_WIDTH,
464 DEFAULT_DISPLAY_HEIGHT);
465 }
466
467 static Rect offsetRectAtZero() {
468 return Rect(DEFAULT_DISPLAY_WIDTH - DEFAULT_DISPLAY_OFFSET,
469 DEFAULT_DISPLAY_HEIGHT - DEFAULT_DISPLAY_OFFSET);
470 }
471
Sally Qi59a9f502021-10-12 18:53:23 +0000472 void invokeDraw(const renderengine::DisplaySettings& settings,
473 const std::vector<renderengine::LayerSettings>& layers) {
Patrick Williams2e9748f2022-08-09 22:48:18 +0000474 ftl::Future<FenceResult> future =
Alec Mourif29700f2023-08-17 21:53:31 +0000475 mRE->drawLayers(settings, layers, mBuffer, base::unique_fd());
Patrick Williams2e9748f2022-08-09 22:48:18 +0000476 ASSERT_TRUE(future.valid());
Sally Qi59a9f502021-10-12 18:53:23 +0000477
Patrick Williams2e9748f2022-08-09 22:48:18 +0000478 auto result = future.get();
479 ASSERT_TRUE(result.ok());
Alec Mouri1089aed2018-10-25 21:33:57 -0700480
Patrick Williams2e9748f2022-08-09 22:48:18 +0000481 auto fence = result.value();
482 fence->waitForever(LOG_TAG);
Alec Mouri1089aed2018-10-25 21:33:57 -0700483 }
484
Alec Mourid43ccab2019-03-13 12:23:45 -0700485 void drawEmptyLayers() {
Alec Mouri6e57f682018-09-29 20:45:08 -0700486 renderengine::DisplaySettings settings;
Sally Qi59a9f502021-10-12 18:53:23 +0000487 std::vector<renderengine::LayerSettings> layers;
Alec Mouric0aae732021-01-12 13:32:18 -0800488 invokeDraw(settings, layers);
Alec Mouri6e57f682018-09-29 20:45:08 -0700489 }
490
Alec Mouri1089aed2018-10-25 21:33:57 -0700491 template <typename SourceVariant>
492 void fillBuffer(half r, half g, half b, half a);
493
494 template <typename SourceVariant>
495 void fillRedBuffer();
496
497 template <typename SourceVariant>
498 void fillGreenBuffer();
499
500 template <typename SourceVariant>
501 void fillBlueBuffer();
502
503 template <typename SourceVariant>
504 void fillRedTransparentBuffer();
505
506 template <typename SourceVariant>
507 void fillRedOffsetBuffer();
508
509 template <typename SourceVariant>
510 void fillBufferPhysicalOffset();
511
512 template <typename SourceVariant>
Alec Mouri5a6d8572020-03-23 23:56:15 -0700513 void fillBufferCheckers(uint32_t rotation);
Alec Mouri1089aed2018-10-25 21:33:57 -0700514
515 template <typename SourceVariant>
516 void fillBufferCheckersRotate0();
517
518 template <typename SourceVariant>
519 void fillBufferCheckersRotate90();
520
521 template <typename SourceVariant>
522 void fillBufferCheckersRotate180();
523
524 template <typename SourceVariant>
525 void fillBufferCheckersRotate270();
526
527 template <typename SourceVariant>
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800528 void fillBufferWithLayerTransform();
529
530 template <typename SourceVariant>
Alec Mouri1089aed2018-10-25 21:33:57 -0700531 void fillBufferLayerTransform();
532
533 template <typename SourceVariant>
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800534 void fillBufferWithColorTransform();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800535
536 template <typename SourceVariant>
Alec Mouri1089aed2018-10-25 21:33:57 -0700537 void fillBufferColorTransform();
538
Alec Mouri7c94edb2018-12-03 21:23:26 -0800539 template <typename SourceVariant>
Sally Qi2019fd22021-11-22 10:19:04 -0800540 void fillBufferWithColorTransformAndSourceDataspace(const ui::Dataspace sourceDataspace);
541
542 template <typename SourceVariant>
543 void fillBufferColorTransformAndSourceDataspace();
544
545 template <typename SourceVariant>
546 void fillBufferWithColorTransformAndOutputDataspace(const ui::Dataspace outputDataspace);
547
548 template <typename SourceVariant>
549 void fillBufferColorTransformAndOutputDataspace();
550
551 template <typename SourceVariant>
KaiChieh Chuangda2845c2020-12-14 16:49:38 +0800552 void fillBufferWithColorTransformZeroLayerAlpha();
553
554 template <typename SourceVariant>
555 void fillBufferColorTransformZeroLayerAlpha();
556
557 template <typename SourceVariant>
Alec Mouri7c94edb2018-12-03 21:23:26 -0800558 void fillRedBufferWithRoundedCorners();
559
560 template <typename SourceVariant>
561 void fillBufferWithRoundedCorners();
562
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000563 template <typename SourceVariant>
Lucas Dupin19c8f0e2019-11-25 17:55:44 -0800564 void fillBufferAndBlurBackground();
565
566 template <typename SourceVariant>
Alec Mourie8489fd2021-04-29 16:08:56 -0700567 void fillSmallLayerAndBlurBackground();
568
569 template <typename SourceVariant>
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000570 void overlayCorners();
571
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800572 void fillRedBufferTextureTransform();
573
574 void fillBufferTextureTransform();
575
576 void fillRedBufferWithPremultiplyAlpha();
577
578 void fillBufferWithPremultiplyAlpha();
579
580 void fillRedBufferWithoutPremultiplyAlpha();
581
582 void fillBufferWithoutPremultiplyAlpha();
583
Alec Mouriac335532018-11-12 15:01:33 -0800584 void fillGreenColorBufferThenClearRegion();
585
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800586 template <typename SourceVariant>
Vishnu Naird9e4f462023-10-06 04:05:45 +0000587 void drawShadow(const renderengine::LayerSettings& castingLayer, const ShadowSettings& shadow,
588 const ubyte4& casterColor, const ubyte4& backgroundColor);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800589
Vishnu Naird9e4f462023-10-06 04:05:45 +0000590 void drawShadowWithoutCaster(const FloatRect& castingBounds, const ShadowSettings& shadow,
Alec Mouribd17b3b2020-12-17 11:08:30 -0800591 const ubyte4& backgroundColor);
592
Alec Mouri5a493722022-01-26 16:43:02 -0800593 // Tonemaps grey values from sourceDataspace -> Display P3 and checks that GPU and CPU
594 // implementations are identical Also implicitly checks that the injected tonemap shader
595 // compiles
596 void tonemap(ui::Dataspace sourceDataspace, std::function<vec3(vec3)> eotf,
597 std::function<vec3(vec3, float)> scaleOotf);
598
Alec Mouric0aae732021-01-12 13:32:18 -0800599 void initializeRenderEngine();
600
601 std::unique_ptr<renderengine::RenderEngine> mRE;
Alec Mouria90a5702021-04-16 16:36:21 +0000602 std::shared_ptr<renderengine::ExternalTexture> mBuffer;
Alec Mouri6e57f682018-09-29 20:45:08 -0700603};
604
Alec Mouric0aae732021-01-12 13:32:18 -0800605void RenderEngineTest::initializeRenderEngine() {
606 const auto& renderEngineFactory = GetParam();
Alec Mouric16974e2022-09-13 17:35:48 +0000607 mRE = renderEngineFactory->createRenderEngine();
Alec Mouria90a5702021-04-16 16:36:21 +0000608 mBuffer = allocateDefaultBuffer();
Alec Mouric0aae732021-01-12 13:32:18 -0800609}
610
Alec Mouri1089aed2018-10-25 21:33:57 -0700611struct ColorSourceVariant {
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800612 static void fillColor(renderengine::LayerSettings& layer, half r, half g, half b,
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800613 RenderEngineTest* /*fixture*/) {
Alec Mouri1089aed2018-10-25 21:33:57 -0700614 layer.source.solidColor = half3(r, g, b);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800615 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700616 }
617};
618
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800619struct RelaxOpaqueBufferVariant {
620 static void setOpaqueBit(renderengine::LayerSettings& layer) {
621 layer.source.buffer.isOpaque = false;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800622 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800623 }
624
625 static uint8_t getAlphaChannel() { return 255; }
626};
627
628struct ForceOpaqueBufferVariant {
629 static void setOpaqueBit(renderengine::LayerSettings& layer) {
630 layer.source.buffer.isOpaque = true;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800631 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800632 }
633
634 static uint8_t getAlphaChannel() {
635 // The isOpaque bit will override the alpha channel, so this should be
636 // arbitrary.
Alec Mouric0aae732021-01-12 13:32:18 -0800637 return 50;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800638 }
639};
640
641template <typename OpaquenessVariant>
642struct BufferSourceVariant {
643 static void fillColor(renderengine::LayerSettings& layer, half r, half g, half b,
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800644 RenderEngineTest* fixture) {
Alec Mouria90a5702021-04-16 16:36:21 +0000645 const auto buf = fixture->allocateSourceBuffer(1, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800646
647 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +0000648 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
649 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800650
Alec Mouria90a5702021-04-16 16:36:21 +0000651 for (int32_t j = 0; j < buf->getBuffer()->getHeight(); j++) {
652 uint8_t* iter = pixels + (buf->getBuffer()->getStride() * j) * 4;
653 for (int32_t i = 0; i < buf->getBuffer()->getWidth(); i++) {
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800654 iter[0] = uint8_t(r * 255);
655 iter[1] = uint8_t(g * 255);
656 iter[2] = uint8_t(b * 255);
657 iter[3] = OpaquenessVariant::getAlphaChannel();
658 iter += 4;
659 }
660 }
661
Alec Mouria90a5702021-04-16 16:36:21 +0000662 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800663
664 layer.source.buffer.buffer = buf;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800665 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800666 OpaquenessVariant::setOpaqueBit(layer);
667 }
668};
669
Alec Mouri1089aed2018-10-25 21:33:57 -0700670template <typename SourceVariant>
671void RenderEngineTest::fillBuffer(half r, half g, half b, half a) {
672 renderengine::DisplaySettings settings;
673 settings.physicalDisplay = fullscreenRect();
674 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800675 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700676
Sally Qi59a9f502021-10-12 18:53:23 +0000677 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700678
679 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800680 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700681 layer.geometry.boundaries = fullscreenRect().toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800682 SourceVariant::fillColor(layer, r, g, b, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700683 layer.alpha = a;
684
Sally Qi59a9f502021-10-12 18:53:23 +0000685 layers.push_back(layer);
Alec Mouri1089aed2018-10-25 21:33:57 -0700686
Alec Mouric0aae732021-01-12 13:32:18 -0800687 invokeDraw(settings, layers);
Alec Mouri1089aed2018-10-25 21:33:57 -0700688}
689
690template <typename SourceVariant>
691void RenderEngineTest::fillRedBuffer() {
692 fillBuffer<SourceVariant>(1.0f, 0.0f, 0.0f, 1.0f);
693 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
694}
695
696template <typename SourceVariant>
697void RenderEngineTest::fillGreenBuffer() {
698 fillBuffer<SourceVariant>(0.0f, 1.0f, 0.0f, 1.0f);
699 expectBufferColor(fullscreenRect(), 0, 255, 0, 255);
700}
701
702template <typename SourceVariant>
703void RenderEngineTest::fillBlueBuffer() {
704 fillBuffer<SourceVariant>(0.0f, 0.0f, 1.0f, 1.0f);
705 expectBufferColor(fullscreenRect(), 0, 0, 255, 255);
706}
707
708template <typename SourceVariant>
709void RenderEngineTest::fillRedTransparentBuffer() {
710 fillBuffer<SourceVariant>(1.0f, 0.0f, 0.0f, .2f);
711 expectBufferColor(fullscreenRect(), 51, 0, 0, 51);
712}
713
714template <typename SourceVariant>
715void RenderEngineTest::fillRedOffsetBuffer() {
716 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800717 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700718 settings.physicalDisplay = offsetRect();
719 settings.clip = offsetRectAtZero();
720
Sally Qi59a9f502021-10-12 18:53:23 +0000721 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700722
723 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800724 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700725 layer.geometry.boundaries = offsetRectAtZero().toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800726 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700727 layer.alpha = 1.0f;
728
Sally Qi59a9f502021-10-12 18:53:23 +0000729 layers.push_back(layer);
Alec Mouric0aae732021-01-12 13:32:18 -0800730 invokeDraw(settings, layers);
Alec Mouri1089aed2018-10-25 21:33:57 -0700731}
732
733template <typename SourceVariant>
734void RenderEngineTest::fillBufferPhysicalOffset() {
735 fillRedOffsetBuffer<SourceVariant>();
736
737 expectBufferColor(Rect(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_WIDTH,
738 DEFAULT_DISPLAY_HEIGHT),
739 255, 0, 0, 255);
740 Rect offsetRegionLeft(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_HEIGHT);
741 Rect offsetRegionTop(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_OFFSET);
742
743 expectBufferColor(offsetRegionLeft, 0, 0, 0, 0);
744 expectBufferColor(offsetRegionTop, 0, 0, 0, 0);
745}
746
747template <typename SourceVariant>
Alec Mouri5a6d8572020-03-23 23:56:15 -0700748void RenderEngineTest::fillBufferCheckers(uint32_t orientationFlag) {
Alec Mouri1089aed2018-10-25 21:33:57 -0700749 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800750 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700751 settings.physicalDisplay = fullscreenRect();
752 // Here logical space is 2x2
753 settings.clip = Rect(2, 2);
Alec Mouri5a6d8572020-03-23 23:56:15 -0700754 settings.orientation = orientationFlag;
Alec Mouri1089aed2018-10-25 21:33:57 -0700755
Sally Qi59a9f502021-10-12 18:53:23 +0000756 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700757
758 renderengine::LayerSettings layerOne;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800759 layerOne.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700760 Rect rectOne(0, 0, 1, 1);
761 layerOne.geometry.boundaries = rectOne.toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800762 SourceVariant::fillColor(layerOne, 1.0f, 0.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700763 layerOne.alpha = 1.0f;
764
765 renderengine::LayerSettings layerTwo;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800766 layerTwo.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700767 Rect rectTwo(0, 1, 1, 2);
768 layerTwo.geometry.boundaries = rectTwo.toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800769 SourceVariant::fillColor(layerTwo, 0.0f, 1.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700770 layerTwo.alpha = 1.0f;
771
772 renderengine::LayerSettings layerThree;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800773 layerThree.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700774 Rect rectThree(1, 0, 2, 1);
775 layerThree.geometry.boundaries = rectThree.toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800776 SourceVariant::fillColor(layerThree, 0.0f, 0.0f, 1.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700777 layerThree.alpha = 1.0f;
778
Sally Qi59a9f502021-10-12 18:53:23 +0000779 layers.push_back(layerOne);
780 layers.push_back(layerTwo);
781 layers.push_back(layerThree);
Alec Mouri1089aed2018-10-25 21:33:57 -0700782
Alec Mouric0aae732021-01-12 13:32:18 -0800783 invokeDraw(settings, layers);
Alec Mouri1089aed2018-10-25 21:33:57 -0700784}
785
786template <typename SourceVariant>
787void RenderEngineTest::fillBufferCheckersRotate0() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700788 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_0);
Alec Mouri1089aed2018-10-25 21:33:57 -0700789 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0,
790 255);
791 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
792 DEFAULT_DISPLAY_HEIGHT / 2),
793 0, 0, 255, 255);
794 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
795 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
796 0, 0, 0, 0);
797 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
798 DEFAULT_DISPLAY_HEIGHT),
799 0, 255, 0, 255);
800}
801
802template <typename SourceVariant>
803void RenderEngineTest::fillBufferCheckersRotate90() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700804 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_90);
Alec Mouri1089aed2018-10-25 21:33:57 -0700805 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 255, 0,
806 255);
807 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
808 DEFAULT_DISPLAY_HEIGHT / 2),
809 255, 0, 0, 255);
810 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
811 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
812 0, 0, 255, 255);
813 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
814 DEFAULT_DISPLAY_HEIGHT),
815 0, 0, 0, 0);
816}
817
818template <typename SourceVariant>
819void RenderEngineTest::fillBufferCheckersRotate180() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700820 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_180);
Alec Mouri1089aed2018-10-25 21:33:57 -0700821 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 0,
822 0);
823 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
824 DEFAULT_DISPLAY_HEIGHT / 2),
825 0, 255, 0, 255);
826 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
827 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
828 255, 0, 0, 255);
829 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
830 DEFAULT_DISPLAY_HEIGHT),
831 0, 0, 255, 255);
832}
833
834template <typename SourceVariant>
835void RenderEngineTest::fillBufferCheckersRotate270() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700836 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_270);
Alec Mouri1089aed2018-10-25 21:33:57 -0700837 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 255,
838 255);
839 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
840 DEFAULT_DISPLAY_HEIGHT / 2),
841 0, 0, 0, 0);
842 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
843 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
844 0, 255, 0, 255);
845 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
846 DEFAULT_DISPLAY_HEIGHT),
847 255, 0, 0, 255);
848}
849
850template <typename SourceVariant>
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800851void RenderEngineTest::fillBufferWithLayerTransform() {
Alec Mouri1089aed2018-10-25 21:33:57 -0700852 renderengine::DisplaySettings settings;
853 settings.physicalDisplay = fullscreenRect();
854 // Here logical space is 2x2
855 settings.clip = Rect(2, 2);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800856 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700857
Sally Qi59a9f502021-10-12 18:53:23 +0000858 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700859
860 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800861 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700862 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
863 // Translate one pixel diagonally
864 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 -0800865 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700866 layer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
867 layer.alpha = 1.0f;
868
Sally Qi59a9f502021-10-12 18:53:23 +0000869 layers.push_back(layer);
Alec Mouri1089aed2018-10-25 21:33:57 -0700870
Alec Mouric0aae732021-01-12 13:32:18 -0800871 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800872}
Alec Mouri1089aed2018-10-25 21:33:57 -0700873
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800874template <typename SourceVariant>
875void RenderEngineTest::fillBufferLayerTransform() {
876 fillBufferWithLayerTransform<SourceVariant>();
Alec Mouri1089aed2018-10-25 21:33:57 -0700877 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 0, 0);
878 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
879 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
880 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
881 255, 0, 0, 255);
882}
883
884template <typename SourceVariant>
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800885void RenderEngineTest::fillBufferWithColorTransform() {
Alec Mouri1089aed2018-10-25 21:33:57 -0700886 renderengine::DisplaySettings settings;
887 settings.physicalDisplay = fullscreenRect();
888 settings.clip = Rect(1, 1);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800889 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700890
Sally Qi59a9f502021-10-12 18:53:23 +0000891 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700892
893 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800894 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700895 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800896 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700897 layer.alpha = 1.0f;
898
899 // construct a fake color matrix
900 // annihilate green and blue channels
KaiChieh Chuang436fc192020-09-07 13:48:42 +0800901 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
Alec Mouri1089aed2018-10-25 21:33:57 -0700902 // set red channel to red + green
903 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
904
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800905 layer.alpha = 1.0f;
906 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
907
Sally Qi59a9f502021-10-12 18:53:23 +0000908 layers.push_back(layer);
Alec Mouri1089aed2018-10-25 21:33:57 -0700909
Alec Mouric0aae732021-01-12 13:32:18 -0800910 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800911}
Alec Mouri1089aed2018-10-25 21:33:57 -0700912
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800913template <typename SourceVariant>
Sally Qi2019fd22021-11-22 10:19:04 -0800914void RenderEngineTest::fillBufferWithColorTransformAndSourceDataspace(
915 const ui::Dataspace sourceDataspace) {
916 renderengine::DisplaySettings settings;
917 settings.physicalDisplay = fullscreenRect();
918 settings.clip = Rect(1, 1);
919 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
920
921 std::vector<renderengine::LayerSettings> layers;
922
923 renderengine::LayerSettings layer;
Sally Qi2019fd22021-11-22 10:19:04 -0800924 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
925 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
Alec Mouric16974e2022-09-13 17:35:48 +0000926 layer.sourceDataspace = sourceDataspace;
Sally Qi2019fd22021-11-22 10:19:04 -0800927 layer.alpha = 1.0f;
928
929 // construct a fake color matrix
930 // annihilate green and blue channels
931 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
932 // set red channel to red + green
933 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
934
935 layer.alpha = 1.0f;
936 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
937
938 layers.push_back(layer);
939
940 invokeDraw(settings, layers);
941}
942
943template <typename SourceVariant>
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800944void RenderEngineTest::fillBufferColorTransform() {
945 fillBufferWithColorTransform<SourceVariant>();
KaiChieh Chuang436fc192020-09-07 13:48:42 +0800946 expectBufferColor(fullscreenRect(), 172, 0, 0, 255, 1);
947}
948
949template <typename SourceVariant>
Sally Qi2019fd22021-11-22 10:19:04 -0800950void RenderEngineTest::fillBufferColorTransformAndSourceDataspace() {
951 unordered_map<ui::Dataspace, ubyte4> dataspaceToColorMap;
Alec Mouric16974e2022-09-13 17:35:48 +0000952 dataspaceToColorMap[ui::Dataspace::V0_BT709] = {77, 0, 0, 255};
953 dataspaceToColorMap[ui::Dataspace::BT2020] = {101, 0, 0, 255};
954 dataspaceToColorMap[ui::Dataspace::ADOBE_RGB] = {75, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -0800955 ui::Dataspace customizedDataspace = static_cast<ui::Dataspace>(
956 ui::Dataspace::STANDARD_BT709 | ui::Dataspace::TRANSFER_GAMMA2_2 |
957 ui::Dataspace::RANGE_FULL);
Alec Mouric16974e2022-09-13 17:35:48 +0000958 dataspaceToColorMap[customizedDataspace] = {61, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -0800959 for (const auto& [sourceDataspace, color] : dataspaceToColorMap) {
960 fillBufferWithColorTransformAndSourceDataspace<SourceVariant>(sourceDataspace);
961 expectBufferColor(fullscreenRect(), color.r, color.g, color.b, color.a, 1);
962 }
963}
964
965template <typename SourceVariant>
966void RenderEngineTest::fillBufferWithColorTransformAndOutputDataspace(
967 const ui::Dataspace outputDataspace) {
968 renderengine::DisplaySettings settings;
969 settings.physicalDisplay = fullscreenRect();
970 settings.clip = Rect(1, 1);
971 settings.outputDataspace = outputDataspace;
972
973 std::vector<renderengine::LayerSettings> layers;
974
975 renderengine::LayerSettings layer;
976 layer.sourceDataspace = ui::Dataspace::V0_SCRGB_LINEAR;
977 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
978 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
979 layer.alpha = 1.0f;
980
981 // construct a fake color matrix
982 // annihilate green and blue channels
983 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
984 // set red channel to red + green
985 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
986
987 layer.alpha = 1.0f;
988 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
989
990 layers.push_back(layer);
991
992 invokeDraw(settings, layers);
993}
994
995template <typename SourceVariant>
996void RenderEngineTest::fillBufferColorTransformAndOutputDataspace() {
997 unordered_map<ui::Dataspace, ubyte4> dataspaceToColorMap;
Alec Mouric16974e2022-09-13 17:35:48 +0000998 dataspaceToColorMap[ui::Dataspace::V0_BT709] = {198, 0, 0, 255};
999 dataspaceToColorMap[ui::Dataspace::BT2020] = {187, 0, 0, 255};
1000 dataspaceToColorMap[ui::Dataspace::ADOBE_RGB] = {192, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -08001001 ui::Dataspace customizedDataspace = static_cast<ui::Dataspace>(
1002 ui::Dataspace::STANDARD_BT709 | ui::Dataspace::TRANSFER_GAMMA2_6 |
1003 ui::Dataspace::RANGE_FULL);
Alec Mouric16974e2022-09-13 17:35:48 +00001004 dataspaceToColorMap[customizedDataspace] = {205, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -08001005 for (const auto& [outputDataspace, color] : dataspaceToColorMap) {
1006 fillBufferWithColorTransformAndOutputDataspace<SourceVariant>(outputDataspace);
1007 expectBufferColor(fullscreenRect(), color.r, color.g, color.b, color.a, 1);
1008 }
1009}
1010
1011template <typename SourceVariant>
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001012void RenderEngineTest::fillBufferWithColorTransformZeroLayerAlpha() {
1013 renderengine::DisplaySettings settings;
1014 settings.physicalDisplay = fullscreenRect();
1015 settings.clip = Rect(1, 1);
1016
Sally Qi59a9f502021-10-12 18:53:23 +00001017 std::vector<renderengine::LayerSettings> layers;
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001018
1019 renderengine::LayerSettings layer;
1020 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1021 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
1022 layer.alpha = 0;
1023
1024 // construct a fake color matrix
1025 // simple inverse color
1026 settings.colorTransform = mat4(-1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 1, 1, 1, 1);
1027
1028 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1029
Sally Qi59a9f502021-10-12 18:53:23 +00001030 layers.push_back(layer);
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001031
Alec Mouric0aae732021-01-12 13:32:18 -08001032 invokeDraw(settings, layers);
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001033}
1034
1035template <typename SourceVariant>
1036void RenderEngineTest::fillBufferColorTransformZeroLayerAlpha() {
1037 fillBufferWithColorTransformZeroLayerAlpha<SourceVariant>();
1038 expectBufferColor(fullscreenRect(), 0, 0, 0, 0);
1039}
1040
1041template <typename SourceVariant>
Alec Mouri7c94edb2018-12-03 21:23:26 -08001042void RenderEngineTest::fillRedBufferWithRoundedCorners() {
1043 renderengine::DisplaySettings settings;
1044 settings.physicalDisplay = fullscreenRect();
1045 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001046 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri7c94edb2018-12-03 21:23:26 -08001047
Sally Qi59a9f502021-10-12 18:53:23 +00001048 std::vector<renderengine::LayerSettings> layers;
Alec Mouri7c94edb2018-12-03 21:23:26 -08001049
1050 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001051 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri7c94edb2018-12-03 21:23:26 -08001052 layer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07001053 layer.geometry.roundedCornersRadius = {5.0f, 5.0f};
Alec Mouri7c94edb2018-12-03 21:23:26 -08001054 layer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
1055 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
1056 layer.alpha = 1.0f;
1057
Sally Qi59a9f502021-10-12 18:53:23 +00001058 layers.push_back(layer);
Alec Mouri7c94edb2018-12-03 21:23:26 -08001059
Alec Mouric0aae732021-01-12 13:32:18 -08001060 invokeDraw(settings, layers);
Alec Mouri7c94edb2018-12-03 21:23:26 -08001061}
1062
1063template <typename SourceVariant>
1064void RenderEngineTest::fillBufferWithRoundedCorners() {
1065 fillRedBufferWithRoundedCorners<SourceVariant>();
1066 // Corners should be ignored...
1067 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 0);
1068 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, 0, DEFAULT_DISPLAY_WIDTH, 1), 0, 0, 0, 0);
1069 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT - 1, 1, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
1070 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1,
1071 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1072 0, 0, 0, 0);
1073 // ...And the non-rounded portion should be red.
1074 // Other pixels may be anti-aliased, so let's not check those.
1075 expectBufferColor(Rect(5, 5, DEFAULT_DISPLAY_WIDTH - 5, DEFAULT_DISPLAY_HEIGHT - 5), 255, 0, 0,
1076 255);
1077}
1078
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001079template <typename SourceVariant>
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001080void RenderEngineTest::fillBufferAndBlurBackground() {
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001081 auto blurRadius = 50;
1082 auto center = DEFAULT_DISPLAY_WIDTH / 2;
1083
1084 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001085 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001086 settings.physicalDisplay = fullscreenRect();
1087 settings.clip = fullscreenRect();
1088
Sally Qi59a9f502021-10-12 18:53:23 +00001089 std::vector<renderengine::LayerSettings> layers;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001090
1091 renderengine::LayerSettings backgroundLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001092 backgroundLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001093 backgroundLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1094 SourceVariant::fillColor(backgroundLayer, 0.0f, 1.0f, 0.0f, this);
1095 backgroundLayer.alpha = 1.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001096 layers.emplace_back(backgroundLayer);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001097
1098 renderengine::LayerSettings leftLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001099 leftLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001100 leftLayer.geometry.boundaries =
1101 Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT).toFloatRect();
1102 SourceVariant::fillColor(leftLayer, 1.0f, 0.0f, 0.0f, this);
1103 leftLayer.alpha = 1.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001104 layers.emplace_back(leftLayer);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001105
1106 renderengine::LayerSettings blurLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001107 blurLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001108 blurLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1109 blurLayer.backgroundBlurRadius = blurRadius;
Derek Sollenbergerecb21462021-01-29 16:53:49 -05001110 SourceVariant::fillColor(blurLayer, 0.0f, 0.0f, 1.0f, this);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001111 blurLayer.alpha = 0;
Sally Qi59a9f502021-10-12 18:53:23 +00001112 layers.emplace_back(blurLayer);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001113
Alec Mouric0aae732021-01-12 13:32:18 -08001114 invokeDraw(settings, layers);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001115
Derek Sollenbergerecb21462021-01-29 16:53:49 -05001116 // solid color
1117 expectBufferColor(Rect(0, 0, 1, 1), 255, 0, 0, 255, 0 /* tolerance */);
1118
Derek Sollenbergerb3998372021-02-16 15:16:56 -05001119 if (mRE->supportsBackgroundBlur()) {
1120 // blurred color (downsampling should result in the center color being close to 128)
1121 expectBufferColor(Rect(center - 1, center - 5, center + 1, center + 5), 128, 128, 0, 255,
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001122 50 /* tolerance */);
Derek Sollenbergerb3998372021-02-16 15:16:56 -05001123 }
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001124}
1125
1126template <typename SourceVariant>
Alec Mourie8489fd2021-04-29 16:08:56 -07001127void RenderEngineTest::fillSmallLayerAndBlurBackground() {
1128 auto blurRadius = 50;
1129 renderengine::DisplaySettings settings;
1130 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1131 settings.physicalDisplay = fullscreenRect();
1132 settings.clip = fullscreenRect();
1133
Sally Qi59a9f502021-10-12 18:53:23 +00001134 std::vector<renderengine::LayerSettings> layers;
Alec Mourie8489fd2021-04-29 16:08:56 -07001135
1136 renderengine::LayerSettings backgroundLayer;
1137 backgroundLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1138 backgroundLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1139 SourceVariant::fillColor(backgroundLayer, 1.0f, 0.0f, 0.0f, this);
1140 backgroundLayer.alpha = 1.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001141 layers.push_back(backgroundLayer);
Alec Mourie8489fd2021-04-29 16:08:56 -07001142
1143 renderengine::LayerSettings blurLayer;
1144 blurLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1145 blurLayer.geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f);
1146 blurLayer.backgroundBlurRadius = blurRadius;
1147 SourceVariant::fillColor(blurLayer, 0.0f, 0.0f, 1.0f, this);
1148 blurLayer.alpha = 0;
Sally Qi59a9f502021-10-12 18:53:23 +00001149 layers.push_back(blurLayer);
Alec Mourie8489fd2021-04-29 16:08:56 -07001150
1151 invokeDraw(settings, layers);
1152
1153 // Give a generous tolerance - the blur rectangle is very small and this test is
1154 // mainly concerned with ensuring that there's no device failure.
1155 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT), 255, 0, 0, 255,
1156 40 /* tolerance */);
1157}
1158
1159template <typename SourceVariant>
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001160void RenderEngineTest::overlayCorners() {
1161 renderengine::DisplaySettings settings;
1162 settings.physicalDisplay = fullscreenRect();
1163 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001164 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001165
Sally Qi59a9f502021-10-12 18:53:23 +00001166 std::vector<renderengine::LayerSettings> layersFirst;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001167
1168 renderengine::LayerSettings layerOne;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001169 layerOne.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001170 layerOne.geometry.boundaries =
1171 FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH / 3.0, DEFAULT_DISPLAY_HEIGHT / 3.0);
1172 SourceVariant::fillColor(layerOne, 1.0f, 0.0f, 0.0f, this);
1173 layerOne.alpha = 0.2;
1174
Sally Qi59a9f502021-10-12 18:53:23 +00001175 layersFirst.push_back(layerOne);
Alec Mouric0aae732021-01-12 13:32:18 -08001176 invokeDraw(settings, layersFirst);
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001177 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3), 51, 0, 0, 51);
1178 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3 + 1, DEFAULT_DISPLAY_HEIGHT / 3 + 1,
1179 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1180 0, 0, 0, 0);
1181
Sally Qi59a9f502021-10-12 18:53:23 +00001182 std::vector<renderengine::LayerSettings> layersSecond;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001183 renderengine::LayerSettings layerTwo;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001184 layerTwo.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001185 layerTwo.geometry.boundaries =
1186 FloatRect(DEFAULT_DISPLAY_WIDTH / 3.0, DEFAULT_DISPLAY_HEIGHT / 3.0,
1187 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT);
1188 SourceVariant::fillColor(layerTwo, 0.0f, 1.0f, 0.0f, this);
1189 layerTwo.alpha = 1.0f;
1190
Sally Qi59a9f502021-10-12 18:53:23 +00001191 layersSecond.push_back(layerTwo);
Alec Mouric0aae732021-01-12 13:32:18 -08001192 invokeDraw(settings, layersSecond);
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001193
1194 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3), 0, 0, 0, 0);
1195 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3 + 1, DEFAULT_DISPLAY_HEIGHT / 3 + 1,
1196 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1197 0, 255, 0, 255);
1198}
1199
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001200void RenderEngineTest::fillRedBufferTextureTransform() {
1201 renderengine::DisplaySettings settings;
1202 settings.physicalDisplay = fullscreenRect();
1203 settings.clip = Rect(1, 1);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001204 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001205
Sally Qi59a9f502021-10-12 18:53:23 +00001206 std::vector<renderengine::LayerSettings> layers;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001207
1208 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001209 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001210 // Here will allocate a checker board texture, but transform texture
1211 // coordinates so that only the upper left is applied.
Alec Mouria90a5702021-04-16 16:36:21 +00001212 const auto buf = allocateSourceBuffer(2, 2);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001213
1214 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00001215 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1216 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001217 // Red top left, Green top right, Blue bottom left, Black bottom right
1218 pixels[0] = 255;
1219 pixels[1] = 0;
1220 pixels[2] = 0;
1221 pixels[3] = 255;
1222 pixels[4] = 0;
1223 pixels[5] = 255;
1224 pixels[6] = 0;
1225 pixels[7] = 255;
1226 pixels[8] = 0;
1227 pixels[9] = 0;
1228 pixels[10] = 255;
1229 pixels[11] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00001230 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001231
1232 layer.source.buffer.buffer = buf;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001233 // Transform coordinates to only be inside the red quadrant.
Alec Mouri4049b532021-10-15 20:59:33 -07001234 layer.source.buffer.textureTransform = mat4::scale(vec4(0.2f, 0.2f, 1.f, 1.f));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001235 layer.alpha = 1.0f;
1236 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1237
Sally Qi59a9f502021-10-12 18:53:23 +00001238 layers.push_back(layer);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001239
Alec Mouric0aae732021-01-12 13:32:18 -08001240 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001241}
1242
1243void RenderEngineTest::fillBufferTextureTransform() {
1244 fillRedBufferTextureTransform();
1245 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
1246}
1247
1248void RenderEngineTest::fillRedBufferWithPremultiplyAlpha() {
1249 renderengine::DisplaySettings settings;
1250 settings.physicalDisplay = fullscreenRect();
1251 // Here logical space is 1x1
1252 settings.clip = Rect(1, 1);
1253
Sally Qi59a9f502021-10-12 18:53:23 +00001254 std::vector<renderengine::LayerSettings> layers;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001255
1256 renderengine::LayerSettings layer;
Alec Mouria90a5702021-04-16 16:36:21 +00001257 const auto buf = allocateSourceBuffer(1, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001258
1259 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00001260 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1261 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001262 pixels[0] = 255;
1263 pixels[1] = 0;
1264 pixels[2] = 0;
1265 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00001266 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001267
1268 layer.source.buffer.buffer = buf;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001269 layer.source.buffer.usePremultipliedAlpha = true;
1270 layer.alpha = 0.5f;
1271 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1272
Sally Qi59a9f502021-10-12 18:53:23 +00001273 layers.push_back(layer);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001274
Alec Mouric0aae732021-01-12 13:32:18 -08001275 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001276}
1277
1278void RenderEngineTest::fillBufferWithPremultiplyAlpha() {
1279 fillRedBufferWithPremultiplyAlpha();
Nolan Scobie01b93b12024-04-03 21:27:34 +00001280 // Different backends and GPUs may round 255 * 0.5 = 127.5 differently, but
1281 // either 127 or 128 are acceptable. Checking both 127 and 128 with a
1282 // tolerance of 1 allows either 127 or 128 to pass, while preventing 126 or
1283 // 129 from erroneously passing.
1284 expectBufferColor(fullscreenRect(), 127, 0, 0, 127, 1);
1285 expectBufferColor(fullscreenRect(), 128, 0, 0, 128, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001286}
1287
1288void RenderEngineTest::fillRedBufferWithoutPremultiplyAlpha() {
1289 renderengine::DisplaySettings settings;
1290 settings.physicalDisplay = fullscreenRect();
1291 // Here logical space is 1x1
1292 settings.clip = Rect(1, 1);
1293
Sally Qi59a9f502021-10-12 18:53:23 +00001294 std::vector<renderengine::LayerSettings> layers;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001295
1296 renderengine::LayerSettings layer;
Alec Mouria90a5702021-04-16 16:36:21 +00001297 const auto buf = allocateSourceBuffer(1, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001298
1299 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00001300 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1301 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001302 pixels[0] = 255;
1303 pixels[1] = 0;
1304 pixels[2] = 0;
1305 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00001306 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001307
1308 layer.source.buffer.buffer = buf;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001309 layer.source.buffer.usePremultipliedAlpha = false;
1310 layer.alpha = 0.5f;
1311 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1312
Sally Qi59a9f502021-10-12 18:53:23 +00001313 layers.push_back(layer);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001314
Alec Mouric0aae732021-01-12 13:32:18 -08001315 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001316}
1317
1318void RenderEngineTest::fillBufferWithoutPremultiplyAlpha() {
1319 fillRedBufferWithoutPremultiplyAlpha();
wukui16f3c0bb2020-08-05 20:35:29 +08001320 expectBufferColor(fullscreenRect(), 128, 0, 0, 128, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001321}
1322
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001323template <typename SourceVariant>
1324void RenderEngineTest::drawShadow(const renderengine::LayerSettings& castingLayer,
Vishnu Naird9e4f462023-10-06 04:05:45 +00001325 const ShadowSettings& shadow, const ubyte4& casterColor,
1326 const ubyte4& backgroundColor) {
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001327 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001328 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001329 settings.physicalDisplay = fullscreenRect();
1330 settings.clip = fullscreenRect();
1331
Sally Qi59a9f502021-10-12 18:53:23 +00001332 std::vector<renderengine::LayerSettings> layers;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001333
1334 // add background layer
1335 renderengine::LayerSettings bgLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001336 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001337 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1338 ColorSourceVariant::fillColor(bgLayer, backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1339 backgroundColor.b / 255.0f, this);
1340 bgLayer.alpha = backgroundColor.a / 255.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001341 layers.push_back(bgLayer);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001342
1343 // add shadow layer
1344 renderengine::LayerSettings shadowLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001345 shadowLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001346 shadowLayer.geometry.boundaries = castingLayer.geometry.boundaries;
1347 shadowLayer.alpha = castingLayer.alpha;
1348 shadowLayer.shadow = shadow;
Sally Qi59a9f502021-10-12 18:53:23 +00001349 layers.push_back(shadowLayer);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001350
1351 // add layer casting the shadow
1352 renderengine::LayerSettings layer = castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001353 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001354 SourceVariant::fillColor(layer, casterColor.r / 255.0f, casterColor.g / 255.0f,
1355 casterColor.b / 255.0f, this);
Sally Qi59a9f502021-10-12 18:53:23 +00001356 layers.push_back(layer);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001357
Alec Mouric0aae732021-01-12 13:32:18 -08001358 invokeDraw(settings, layers);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001359}
1360
Alec Mouribd17b3b2020-12-17 11:08:30 -08001361void RenderEngineTest::drawShadowWithoutCaster(const FloatRect& castingBounds,
Vishnu Naird9e4f462023-10-06 04:05:45 +00001362 const ShadowSettings& shadow,
Alec Mouribd17b3b2020-12-17 11:08:30 -08001363 const ubyte4& backgroundColor) {
1364 renderengine::DisplaySettings settings;
1365 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1366 settings.physicalDisplay = fullscreenRect();
1367 settings.clip = fullscreenRect();
1368
Sally Qi59a9f502021-10-12 18:53:23 +00001369 std::vector<renderengine::LayerSettings> layers;
Alec Mouribd17b3b2020-12-17 11:08:30 -08001370
1371 // add background layer
1372 renderengine::LayerSettings bgLayer;
1373 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1374 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1375 ColorSourceVariant::fillColor(bgLayer, backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1376 backgroundColor.b / 255.0f, this);
1377 bgLayer.alpha = backgroundColor.a / 255.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001378 layers.push_back(bgLayer);
Alec Mouribd17b3b2020-12-17 11:08:30 -08001379
1380 // add shadow layer
1381 renderengine::LayerSettings shadowLayer;
1382 shadowLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1383 shadowLayer.geometry.boundaries = castingBounds;
Derek Sollenbergerc31985e2021-05-18 16:38:17 -04001384 shadowLayer.skipContentDraw = true;
Alec Mouribd17b3b2020-12-17 11:08:30 -08001385 shadowLayer.alpha = 1.0f;
1386 ColorSourceVariant::fillColor(shadowLayer, 0, 0, 0, this);
1387 shadowLayer.shadow = shadow;
Sally Qi59a9f502021-10-12 18:53:23 +00001388 layers.push_back(shadowLayer);
Alec Mouribd17b3b2020-12-17 11:08:30 -08001389
Alec Mouric0aae732021-01-12 13:32:18 -08001390 invokeDraw(settings, layers);
Alec Mouribd17b3b2020-12-17 11:08:30 -08001391}
1392
Alec Mouri5a493722022-01-26 16:43:02 -08001393void RenderEngineTest::tonemap(ui::Dataspace sourceDataspace, std::function<vec3(vec3)> eotf,
1394 std::function<vec3(vec3, float)> scaleOotf) {
1395 constexpr int32_t kGreyLevels = 256;
1396
1397 const auto rect = Rect(0, 0, kGreyLevels, 1);
1398
1399 constexpr float kMaxLuminance = 750.f;
1400 constexpr float kCurrentLuminanceNits = 500.f;
1401 const renderengine::DisplaySettings display{
1402 .physicalDisplay = rect,
1403 .clip = rect,
1404 .maxLuminance = kMaxLuminance,
1405 .currentLuminanceNits = kCurrentLuminanceNits,
1406 .outputDataspace = ui::Dataspace::DISPLAY_P3,
1407 };
1408
1409 auto buf = std::make_shared<
1410 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07001411 ExternalTexture>(sp<GraphicBuffer>::make(kGreyLevels, 1,
1412 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1413 GRALLOC_USAGE_SW_READ_OFTEN |
1414 GRALLOC_USAGE_SW_WRITE_OFTEN |
1415 GRALLOC_USAGE_HW_RENDER |
1416 GRALLOC_USAGE_HW_TEXTURE,
1417 "input"),
Alec Mouri5a493722022-01-26 16:43:02 -08001418 *mRE,
1419 renderengine::impl::ExternalTexture::Usage::READABLE |
1420 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
1421 ASSERT_EQ(0, buf->getBuffer()->initCheck());
1422 {
1423 uint8_t* pixels;
1424 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1425 reinterpret_cast<void**>(&pixels));
1426
1427 uint8_t color = 0;
1428 for (int32_t j = 0; j < buf->getBuffer()->getHeight(); j++) {
1429 uint8_t* dest = pixels + (buf->getBuffer()->getStride() * j * 4);
1430 for (int32_t i = 0; i < buf->getBuffer()->getWidth(); i++) {
1431 dest[0] = color;
1432 dest[1] = color;
1433 dest[2] = color;
1434 dest[3] = 255;
1435 color++;
1436 dest += 4;
1437 }
1438 }
1439 buf->getBuffer()->unlock();
1440 }
1441
1442 mBuffer = std::make_shared<
1443 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07001444 ExternalTexture>(sp<GraphicBuffer>::make(kGreyLevels, 1,
1445 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1446 GRALLOC_USAGE_SW_READ_OFTEN |
1447 GRALLOC_USAGE_SW_WRITE_OFTEN |
1448 GRALLOC_USAGE_HW_RENDER |
1449 GRALLOC_USAGE_HW_TEXTURE,
1450 "output"),
Alec Mouri5a493722022-01-26 16:43:02 -08001451 *mRE,
1452 renderengine::impl::ExternalTexture::Usage::READABLE |
1453 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
1454 ASSERT_EQ(0, mBuffer->getBuffer()->initCheck());
1455
1456 const renderengine::LayerSettings layer{.geometry.boundaries = rect.toFloatRect(),
1457 .source =
1458 renderengine::PixelSource{
1459 .buffer =
1460 renderengine::Buffer{
1461 .buffer =
1462 std::move(buf),
1463 .usePremultipliedAlpha =
1464 true,
1465 },
1466 },
1467 .alpha = 1.0f,
1468 .sourceDataspace = sourceDataspace};
1469
1470 std::vector<renderengine::LayerSettings> layers{layer};
1471 invokeDraw(display, layers);
1472
1473 ColorSpace displayP3 = ColorSpace::DisplayP3();
1474 ColorSpace bt2020 = ColorSpace::BT2020();
1475
1476 tonemap::Metadata metadata{.displayMaxLuminance = 750.0f};
1477
1478 auto generator = [=](Point location) {
1479 const double normColor = static_cast<double>(location.x) / (kGreyLevels - 1);
1480 const vec3 rgb = vec3(normColor, normColor, normColor);
1481
1482 const vec3 linearRGB = eotf(rgb);
1483
1484 const vec3 xyz = bt2020.getRGBtoXYZ() * linearRGB;
1485
1486 const vec3 scaledXYZ = scaleOotf(xyz, kCurrentLuminanceNits);
Alec Mouri196b0f22022-03-04 22:13:48 +00001487 const auto gains =
Alec Mouri5a493722022-01-26 16:43:02 -08001488 tonemap::getToneMapper()
1489 ->lookupTonemapGain(static_cast<aidl::android::hardware::graphics::common::
1490 Dataspace>(sourceDataspace),
1491 static_cast<aidl::android::hardware::graphics::common::
1492 Dataspace>(
1493 ui::Dataspace::DISPLAY_P3),
Alec Mouri196b0f22022-03-04 22:13:48 +00001494 {tonemap::
1495 Color{.linearRGB =
1496 scaleOotf(linearRGB,
1497 kCurrentLuminanceNits),
1498 .xyz = scaledXYZ}},
Alec Mouri5a493722022-01-26 16:43:02 -08001499 metadata);
Alec Mouri196b0f22022-03-04 22:13:48 +00001500 EXPECT_EQ(1, gains.size());
1501 const double gain = gains.front();
Alec Mouri5a493722022-01-26 16:43:02 -08001502 const vec3 normalizedXYZ = scaledXYZ * gain / metadata.displayMaxLuminance;
1503
1504 const vec3 targetRGB = OETF_sRGB(displayP3.getXYZtoRGB() * normalizedXYZ) * 255;
1505 return ubyte4(static_cast<uint8_t>(targetRGB.r), static_cast<uint8_t>(targetRGB.g),
1506 static_cast<uint8_t>(targetRGB.b), 255);
1507 };
1508
1509 expectBufferColor(Rect(kGreyLevels, 1), generator, 2);
1510}
1511
Nolan Scobie488101b2024-05-20 13:32:13 -04001512// TODO: b/341728634 - Clean up conditional compilation.
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001513INSTANTIATE_TEST_SUITE_P(PerRenderEngineType, RenderEngineTest,
Alec Mouric16974e2022-09-13 17:35:48 +00001514 testing::Values(std::make_shared<SkiaGLESRenderEngineFactory>(),
Nolan Scobie488101b2024-05-20 13:32:13 -04001515 std::make_shared<GaneshVkRenderEngineFactory>()
1516#if COMPILE_GRAPHITE_RENDERENGINE
1517 ,
1518 std::make_shared<GraphiteVkRenderEngineFactory>()
1519#endif
1520 ));
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001521
1522TEST_P(RenderEngineTest, drawLayers_noLayersToDraw) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001523 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001524 GTEST_SKIP();
1525 }
Alec Mouric0aae732021-01-12 13:32:18 -08001526 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001527 drawEmptyLayers();
1528}
1529
Sally Qi1fed86e2022-06-23 15:33:52 -07001530TEST_P(RenderEngineTest, drawLayers_fillRedBufferAndEmptyBuffer) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001531 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001532 GTEST_SKIP();
1533 }
Sally Qi1fed86e2022-06-23 15:33:52 -07001534 initializeRenderEngine();
1535 renderengine::DisplaySettings settings;
1536 settings.physicalDisplay = fullscreenRect();
1537 settings.clip = fullscreenRect();
1538 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1539
1540 // add a red layer
1541 renderengine::LayerSettings layerOne{
1542 .geometry.boundaries = fullscreenRect().toFloatRect(),
1543 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
1544 .alpha = 1.f,
1545 };
1546
1547 std::vector<renderengine::LayerSettings> layersFirst{layerOne};
1548 invokeDraw(settings, layersFirst);
1549 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
1550
1551 // re-draw with an empty layer above it, and we get a transparent black one
1552 std::vector<renderengine::LayerSettings> layersSecond;
1553 invokeDraw(settings, layersSecond);
1554 expectBufferColor(fullscreenRect(), 0, 0, 0, 0);
1555}
1556
Ana Krulec07b98df2021-01-07 14:38:40 -08001557TEST_P(RenderEngineTest, drawLayers_withoutBuffers_withColorTransform) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001558 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001559 GTEST_SKIP();
1560 }
Alec Mouria90a5702021-04-16 16:36:21 +00001561 initializeRenderEngine();
Ana Krulec07b98df2021-01-07 14:38:40 -08001562
1563 renderengine::DisplaySettings settings;
1564 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1565 settings.physicalDisplay = fullscreenRect();
1566 settings.clip = fullscreenRect();
1567
1568 // 255, 255, 255, 255 is full opaque white.
Alec Mouri4049b532021-10-15 20:59:33 -07001569 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
1570 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Ana Krulec07b98df2021-01-07 14:38:40 -08001571 // Create layer with given color.
1572 renderengine::LayerSettings bgLayer;
1573 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1574 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1575 bgLayer.source.solidColor = half3(backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1576 backgroundColor.b / 255.0f);
1577 bgLayer.alpha = backgroundColor.a / 255.0f;
1578 // Transform the red color.
1579 bgLayer.colorTransform = mat4(-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
1580
Sally Qi59a9f502021-10-12 18:53:23 +00001581 std::vector<renderengine::LayerSettings> layers;
1582 layers.push_back(bgLayer);
Ana Krulec07b98df2021-01-07 14:38:40 -08001583
Alec Mouric0aae732021-01-12 13:32:18 -08001584 invokeDraw(settings, layers);
Ana Krulec07b98df2021-01-07 14:38:40 -08001585
1586 // Expect to see full opaque pixel (with inverted red from the transform).
Alec Mouric0aae732021-01-12 13:32:18 -08001587 expectBufferColor(Rect(0, 0, 10, 10), 0.f, backgroundColor.g, backgroundColor.b,
Ana Krulec07b98df2021-01-07 14:38:40 -08001588 backgroundColor.a);
1589}
1590
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001591TEST_P(RenderEngineTest, drawLayers_nullOutputBuffer) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001592 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001593 GTEST_SKIP();
1594 }
Alec Mouric0aae732021-01-12 13:32:18 -08001595 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001596
Alec Mourid43ccab2019-03-13 12:23:45 -07001597 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001598 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Sally Qi59a9f502021-10-12 18:53:23 +00001599 std::vector<renderengine::LayerSettings> layers;
Alec Mourid43ccab2019-03-13 12:23:45 -07001600 renderengine::LayerSettings layer;
1601 layer.geometry.boundaries = fullscreenRect().toFloatRect();
1602 BufferSourceVariant<ForceOpaqueBufferVariant>::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
Sally Qi59a9f502021-10-12 18:53:23 +00001603 layers.push_back(layer);
Alec Mourif29700f2023-08-17 21:53:31 +00001604 ftl::Future<FenceResult> future = mRE->drawLayers(settings, layers, nullptr, base::unique_fd());
Alec Mourid43ccab2019-03-13 12:23:45 -07001605
Patrick Williams2e9748f2022-08-09 22:48:18 +00001606 ASSERT_TRUE(future.valid());
1607 auto result = future.get();
1608 ASSERT_FALSE(result.ok());
1609 ASSERT_EQ(BAD_VALUE, result.error());
Alec Mourid43ccab2019-03-13 12:23:45 -07001610}
1611
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001612TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001613 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001614 GTEST_SKIP();
1615 }
Alec Mouric0aae732021-01-12 13:32:18 -08001616 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001617 fillRedBuffer<ColorSourceVariant>();
1618}
1619
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001620TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001621 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001622 GTEST_SKIP();
1623 }
Alec Mouric0aae732021-01-12 13:32:18 -08001624 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001625 fillGreenBuffer<ColorSourceVariant>();
1626}
1627
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001628TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001629 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001630 GTEST_SKIP();
1631 }
Alec Mouric0aae732021-01-12 13:32:18 -08001632 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001633 fillBlueBuffer<ColorSourceVariant>();
1634}
1635
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001636TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001637 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001638 GTEST_SKIP();
1639 }
Alec Mouric0aae732021-01-12 13:32:18 -08001640 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001641 fillRedTransparentBuffer<ColorSourceVariant>();
1642}
1643
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001644TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001645 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001646 GTEST_SKIP();
1647 }
Alec Mouric0aae732021-01-12 13:32:18 -08001648 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001649 fillBufferPhysicalOffset<ColorSourceVariant>();
1650}
1651
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001652TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001653 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001654 GTEST_SKIP();
1655 }
Alec Mouric0aae732021-01-12 13:32:18 -08001656 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001657 fillBufferCheckersRotate0<ColorSourceVariant>();
1658}
1659
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001660TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001661 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001662 GTEST_SKIP();
1663 }
Alec Mouric0aae732021-01-12 13:32:18 -08001664 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001665 fillBufferCheckersRotate90<ColorSourceVariant>();
1666}
1667
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001668TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001669 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001670 GTEST_SKIP();
1671 }
Alec Mouric0aae732021-01-12 13:32:18 -08001672 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001673 fillBufferCheckersRotate180<ColorSourceVariant>();
1674}
1675
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001676TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001677 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001678 GTEST_SKIP();
1679 }
Alec Mouric0aae732021-01-12 13:32:18 -08001680 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001681 fillBufferCheckersRotate270<ColorSourceVariant>();
1682}
1683
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001684TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001685 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001686 GTEST_SKIP();
1687 }
Alec Mouric0aae732021-01-12 13:32:18 -08001688 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001689 fillBufferLayerTransform<ColorSourceVariant>();
1690}
1691
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001692TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001693 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001694 GTEST_SKIP();
1695 }
Alec Mouric0aae732021-01-12 13:32:18 -08001696 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08001697 fillBufferColorTransform<ColorSourceVariant>();
1698}
1699
Sally Qi2019fd22021-11-22 10:19:04 -08001700TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_sourceDataspace) {
1701 const auto& renderEngineFactory = GetParam();
1702 // skip for non color management
Leon Scroggins III696bf932024-01-24 15:21:05 -05001703 if (!renderEngineFactory->apiSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001704 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001705 }
1706
1707 initializeRenderEngine();
1708 fillBufferColorTransformAndSourceDataspace<ColorSourceVariant>();
1709}
1710
1711TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_outputDataspace) {
1712 const auto& renderEngineFactory = GetParam();
1713 // skip for non color management
Leon Scroggins III696bf932024-01-24 15:21:05 -05001714 if (!renderEngineFactory->apiSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001715 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001716 }
1717
1718 initializeRenderEngine();
1719 fillBufferColorTransformAndOutputDataspace<ColorSourceVariant>();
1720}
1721
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001722TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001723 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001724 GTEST_SKIP();
1725 }
Alec Mouric0aae732021-01-12 13:32:18 -08001726 initializeRenderEngine();
Alec Mouri7c94edb2018-12-03 21:23:26 -08001727 fillBufferWithRoundedCorners<ColorSourceVariant>();
1728}
1729
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001730TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001731 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001732 GTEST_SKIP();
1733 }
Alec Mouric0aae732021-01-12 13:32:18 -08001734 initializeRenderEngine();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001735 fillBufferColorTransformZeroLayerAlpha<ColorSourceVariant>();
1736}
1737
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001738TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001739 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001740 GTEST_SKIP();
1741 }
Alec Mouric0aae732021-01-12 13:32:18 -08001742 initializeRenderEngine();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001743 fillBufferAndBlurBackground<ColorSourceVariant>();
1744}
1745
Alec Mourie8489fd2021-04-29 16:08:56 -07001746TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001747 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001748 GTEST_SKIP();
1749 }
Alec Mourie8489fd2021-04-29 16:08:56 -07001750 initializeRenderEngine();
1751 fillSmallLayerAndBlurBackground<ColorSourceVariant>();
1752}
1753
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001754TEST_P(RenderEngineTest, drawLayers_overlayCorners_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001755 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001756 GTEST_SKIP();
1757 }
Alec Mouric0aae732021-01-12 13:32:18 -08001758 initializeRenderEngine();
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001759 overlayCorners<ColorSourceVariant>();
1760}
1761
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001762TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001763 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001764 GTEST_SKIP();
1765 }
Alec Mouric0aae732021-01-12 13:32:18 -08001766 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001767 fillRedBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1768}
1769
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001770TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001771 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001772 GTEST_SKIP();
1773 }
Alec Mouric0aae732021-01-12 13:32:18 -08001774 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001775 fillGreenBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1776}
1777
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001778TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001779 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001780 GTEST_SKIP();
1781 }
Alec Mouric0aae732021-01-12 13:32:18 -08001782 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001783 fillBlueBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1784}
1785
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001786TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001787 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001788 GTEST_SKIP();
1789 }
Alec Mouric0aae732021-01-12 13:32:18 -08001790 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001791 fillRedTransparentBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1792}
1793
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001794TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001795 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001796 GTEST_SKIP();
1797 }
Alec Mouric0aae732021-01-12 13:32:18 -08001798 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001799 fillBufferPhysicalOffset<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1800}
1801
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001802TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001803 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001804 GTEST_SKIP();
1805 }
Alec Mouric0aae732021-01-12 13:32:18 -08001806 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001807 fillBufferCheckersRotate0<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1808}
1809
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001810TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001811 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001812 GTEST_SKIP();
1813 }
Alec Mouric0aae732021-01-12 13:32:18 -08001814 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001815 fillBufferCheckersRotate90<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1816}
1817
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001818TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001819 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001820 GTEST_SKIP();
1821 }
Alec Mouric0aae732021-01-12 13:32:18 -08001822 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001823 fillBufferCheckersRotate180<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1824}
1825
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001826TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001827 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001828 GTEST_SKIP();
1829 }
Alec Mouric0aae732021-01-12 13:32:18 -08001830 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001831 fillBufferCheckersRotate270<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1832}
1833
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001834TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001835 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001836 GTEST_SKIP();
1837 }
Alec Mouric0aae732021-01-12 13:32:18 -08001838 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001839 fillBufferLayerTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1840}
1841
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001842TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001843 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001844 GTEST_SKIP();
1845 }
Alec Mouric0aae732021-01-12 13:32:18 -08001846 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08001847 fillBufferColorTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1848}
1849
Sally Qi2019fd22021-11-22 10:19:04 -08001850TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndSourceDataspace_opaqueBufferSource) {
1851 const auto& renderEngineFactory = GetParam();
1852 // skip for non color management
Leon Scroggins III696bf932024-01-24 15:21:05 -05001853 if (!renderEngineFactory->apiSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001854 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001855 }
1856
1857 initializeRenderEngine();
1858 fillBufferColorTransformAndSourceDataspace<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1859}
1860
1861TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndOutputDataspace_opaqueBufferSource) {
1862 const auto& renderEngineFactory = GetParam();
1863 // skip for non color management
Leon Scroggins III696bf932024-01-24 15:21:05 -05001864 if (!renderEngineFactory->apiSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001865 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001866 }
1867
1868 initializeRenderEngine();
1869 fillBufferColorTransformAndOutputDataspace<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1870}
1871
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001872TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001873 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001874 GTEST_SKIP();
1875 }
Alec Mouric0aae732021-01-12 13:32:18 -08001876 initializeRenderEngine();
Alec Mouri7c94edb2018-12-03 21:23:26 -08001877 fillBufferWithRoundedCorners<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1878}
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001879
Alec Mouric0aae732021-01-12 13:32:18 -08001880TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001881 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001882 GTEST_SKIP();
1883 }
Alec Mouric0aae732021-01-12 13:32:18 -08001884 initializeRenderEngine();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001885 fillBufferColorTransformZeroLayerAlpha<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1886}
Alec Mouri7c94edb2018-12-03 21:23:26 -08001887
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001888TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001889 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001890 GTEST_SKIP();
1891 }
Alec Mouric0aae732021-01-12 13:32:18 -08001892 initializeRenderEngine();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001893 fillBufferAndBlurBackground<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1894}
1895
Alec Mourie8489fd2021-04-29 16:08:56 -07001896TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001897 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001898 GTEST_SKIP();
1899 }
Alec Mourie8489fd2021-04-29 16:08:56 -07001900 initializeRenderEngine();
1901 fillSmallLayerAndBlurBackground<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1902}
1903
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001904TEST_P(RenderEngineTest, drawLayers_overlayCorners_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001905 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001906 GTEST_SKIP();
1907 }
Alec Mouric0aae732021-01-12 13:32:18 -08001908 initializeRenderEngine();
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001909 overlayCorners<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1910}
1911
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001912TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001913 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001914 GTEST_SKIP();
1915 }
Alec Mouric0aae732021-01-12 13:32:18 -08001916 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001917 fillRedBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1918}
1919
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001920TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001921 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001922 GTEST_SKIP();
1923 }
Alec Mouric0aae732021-01-12 13:32:18 -08001924 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001925 fillGreenBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1926}
1927
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001928TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001929 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001930 GTEST_SKIP();
1931 }
Alec Mouric0aae732021-01-12 13:32:18 -08001932 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001933 fillBlueBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1934}
1935
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001936TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001937 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001938 GTEST_SKIP();
1939 }
Alec Mouric0aae732021-01-12 13:32:18 -08001940 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001941 fillRedTransparentBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1942}
1943
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001944TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001945 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001946 GTEST_SKIP();
1947 }
Alec Mouric0aae732021-01-12 13:32:18 -08001948 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001949 fillBufferPhysicalOffset<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1950}
1951
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001952TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001953 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001954 GTEST_SKIP();
1955 }
Alec Mouric0aae732021-01-12 13:32:18 -08001956 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001957 fillBufferCheckersRotate0<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1958}
1959
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001960TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001961 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001962 GTEST_SKIP();
1963 }
Alec Mouric0aae732021-01-12 13:32:18 -08001964 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001965 fillBufferCheckersRotate90<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1966}
1967
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001968TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001969 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001970 GTEST_SKIP();
1971 }
Alec Mouric0aae732021-01-12 13:32:18 -08001972 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001973 fillBufferCheckersRotate180<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1974}
1975
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001976TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001977 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001978 GTEST_SKIP();
1979 }
Alec Mouric0aae732021-01-12 13:32:18 -08001980 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001981 fillBufferCheckersRotate270<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1982}
1983
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001984TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001985 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001986 GTEST_SKIP();
1987 }
Alec Mouric0aae732021-01-12 13:32:18 -08001988 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001989 fillBufferLayerTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1990}
1991
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001992TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001993 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001994 GTEST_SKIP();
1995 }
Alec Mouric0aae732021-01-12 13:32:18 -08001996 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08001997 fillBufferColorTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1998}
1999
Sally Qi2019fd22021-11-22 10:19:04 -08002000TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndSourceDataspace_bufferSource) {
2001 const auto& renderEngineFactory = GetParam();
2002 // skip for non color management
Leon Scroggins III696bf932024-01-24 15:21:05 -05002003 if (!renderEngineFactory->apiSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00002004 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08002005 }
2006
2007 initializeRenderEngine();
2008 fillBufferColorTransformAndSourceDataspace<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2009}
2010
2011TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndOutputDataspace_bufferSource) {
2012 const auto& renderEngineFactory = GetParam();
2013 // skip for non color management
Leon Scroggins III696bf932024-01-24 15:21:05 -05002014 if (!renderEngineFactory->apiSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00002015 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08002016 }
2017
2018 initializeRenderEngine();
2019 fillBufferColorTransformAndOutputDataspace<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2020}
2021
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002022TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002023 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002024 GTEST_SKIP();
2025 }
Alec Mouric0aae732021-01-12 13:32:18 -08002026 initializeRenderEngine();
Alec Mouri7c94edb2018-12-03 21:23:26 -08002027 fillBufferWithRoundedCorners<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2028}
2029
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08002030TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002031 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002032 GTEST_SKIP();
2033 }
Alec Mouric0aae732021-01-12 13:32:18 -08002034 initializeRenderEngine();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08002035 fillBufferColorTransformZeroLayerAlpha<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2036}
2037
Nathaniel Nifong53494f32021-04-30 14:05:39 -04002038TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002039 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002040 GTEST_SKIP();
2041 }
Alec Mouric0aae732021-01-12 13:32:18 -08002042 initializeRenderEngine();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08002043 fillBufferAndBlurBackground<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2044}
2045
Alec Mourie8489fd2021-04-29 16:08:56 -07002046TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002047 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002048 GTEST_SKIP();
2049 }
Alec Mourie8489fd2021-04-29 16:08:56 -07002050 initializeRenderEngine();
2051 fillSmallLayerAndBlurBackground<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2052}
2053
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002054TEST_P(RenderEngineTest, drawLayers_overlayCorners_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002055 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002056 GTEST_SKIP();
2057 }
Alec Mouric0aae732021-01-12 13:32:18 -08002058 initializeRenderEngine();
Alec Mourie7d1d4a2019-02-05 01:13:46 +00002059 overlayCorners<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2060}
2061
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002062TEST_P(RenderEngineTest, drawLayers_fillBufferTextureTransform) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002063 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002064 GTEST_SKIP();
2065 }
Alec Mouric0aae732021-01-12 13:32:18 -08002066 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002067 fillBufferTextureTransform();
2068}
2069
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002070TEST_P(RenderEngineTest, drawLayers_fillBuffer_premultipliesAlpha) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002071 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002072 GTEST_SKIP();
2073 }
Alec Mouric0aae732021-01-12 13:32:18 -08002074 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002075 fillBufferWithPremultiplyAlpha();
2076}
2077
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002078TEST_P(RenderEngineTest, drawLayers_fillBuffer_withoutPremultiplyingAlpha) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002079 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002080 GTEST_SKIP();
2081 }
Alec Mouric0aae732021-01-12 13:32:18 -08002082 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002083 fillBufferWithoutPremultiplyAlpha();
2084}
2085
Alec Mouribd17b3b2020-12-17 11:08:30 -08002086TEST_P(RenderEngineTest, drawLayers_fillShadow_castsWithoutCasterLayer) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002087 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002088 GTEST_SKIP();
2089 }
Alec Mouric0aae732021-01-12 13:32:18 -08002090 initializeRenderEngine();
Alec Mouribd17b3b2020-12-17 11:08:30 -08002091
Alec Mouri4049b532021-10-15 20:59:33 -07002092 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2093 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Alec Mouribd17b3b2020-12-17 11:08:30 -08002094 const float shadowLength = 5.0f;
2095 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2096 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
Vishnu Naird9e4f462023-10-06 04:05:45 +00002097 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2098 shadowLength, false /* casterIsTranslucent */);
Alec Mouribd17b3b2020-12-17 11:08:30 -08002099
2100 drawShadowWithoutCaster(casterBounds.toFloatRect(), settings, backgroundColor);
2101 expectShadowColorWithoutCaster(casterBounds.toFloatRect(), settings, backgroundColor);
2102}
2103
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002104TEST_P(RenderEngineTest, drawLayers_fillShadow_casterLayerMinSize) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002105 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002106 GTEST_SKIP();
2107 }
Alec Mouric0aae732021-01-12 13:32:18 -08002108 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002109
Alec Mouri4049b532021-10-15 20:59:33 -07002110 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2111 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2112 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2113 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002114 const float shadowLength = 5.0f;
2115 Rect casterBounds(1, 1);
2116 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2117 renderengine::LayerSettings castingLayer;
2118 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2119 castingLayer.alpha = 1.0f;
Vishnu Naird9e4f462023-10-06 04:05:45 +00002120 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2121 shadowLength, false /* casterIsTranslucent */);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002122
2123 drawShadow<ColorSourceVariant>(castingLayer, settings, casterColor, backgroundColor);
2124 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2125}
2126
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002127TEST_P(RenderEngineTest, drawLayers_fillShadow_casterColorLayer) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002128 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002129 GTEST_SKIP();
2130 }
Alec Mouric0aae732021-01-12 13:32:18 -08002131 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002132
Alec Mouri4049b532021-10-15 20:59:33 -07002133 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2134 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2135 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2136 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002137 const float shadowLength = 5.0f;
2138 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2139 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2140 renderengine::LayerSettings castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002141 castingLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002142 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2143 castingLayer.alpha = 1.0f;
Vishnu Naird9e4f462023-10-06 04:05:45 +00002144 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2145 shadowLength, false /* casterIsTranslucent */);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002146
2147 drawShadow<ColorSourceVariant>(castingLayer, settings, casterColor, backgroundColor);
2148 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2149}
2150
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002151TEST_P(RenderEngineTest, drawLayers_fillShadow_casterOpaqueBufferLayer) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002152 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002153 GTEST_SKIP();
2154 }
Alec Mouric0aae732021-01-12 13:32:18 -08002155 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002156
Alec Mouri4049b532021-10-15 20:59:33 -07002157 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2158 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2159 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2160 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002161 const float shadowLength = 5.0f;
2162 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2163 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2164 renderengine::LayerSettings castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002165 castingLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002166 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2167 castingLayer.alpha = 1.0f;
Vishnu Naird9e4f462023-10-06 04:05:45 +00002168 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2169 shadowLength, false /* casterIsTranslucent */);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002170
2171 drawShadow<BufferSourceVariant<ForceOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2172 backgroundColor);
2173 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2174}
2175
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002176TEST_P(RenderEngineTest, drawLayers_fillShadow_casterWithRoundedCorner) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002177 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002178 GTEST_SKIP();
2179 }
Alec Mouric0aae732021-01-12 13:32:18 -08002180 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002181
Alec Mouri4049b532021-10-15 20:59:33 -07002182 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2183 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2184 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2185 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002186 const float shadowLength = 5.0f;
2187 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2188 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2189 renderengine::LayerSettings castingLayer;
2190 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002191 castingLayer.geometry.roundedCornersRadius = {3.0f, 3.0f};
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002192 castingLayer.geometry.roundedCornersCrop = casterBounds.toFloatRect();
2193 castingLayer.alpha = 1.0f;
Vishnu Naird9e4f462023-10-06 04:05:45 +00002194 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2195 shadowLength, false /* casterIsTranslucent */);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002196
2197 drawShadow<BufferSourceVariant<ForceOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2198 backgroundColor);
2199 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2200}
2201
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002202TEST_P(RenderEngineTest, drawLayers_fillShadow_translucentCasterWithAlpha) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002203 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002204 GTEST_SKIP();
2205 }
Alec Mouric0aae732021-01-12 13:32:18 -08002206 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002207
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002208 const ubyte4 casterColor(255, 0, 0, 255);
2209 const ubyte4 backgroundColor(255, 255, 255, 255);
2210 const float shadowLength = 5.0f;
2211 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2212 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2213 renderengine::LayerSettings castingLayer;
2214 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2215 castingLayer.alpha = 0.5f;
Vishnu Naird9e4f462023-10-06 04:05:45 +00002216 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2217 shadowLength, true /* casterIsTranslucent */);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002218
2219 drawShadow<BufferSourceVariant<RelaxOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2220 backgroundColor);
2221
2222 // verify only the background since the shadow will draw behind the caster
2223 const float shadowInset = settings.length * -1.0f;
2224 const Rect casterWithShadow =
2225 Rect(casterBounds).inset(shadowInset, shadowInset, shadowInset, shadowInset);
2226 const Region backgroundRegion = Region(fullscreenRect()).subtractSelf(casterWithShadow);
2227 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
2228 backgroundColor.a);
2229}
2230
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002231TEST_P(RenderEngineTest, cleanupPostRender_cleansUpOnce) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002232 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002233 GTEST_SKIP();
2234 }
Alec Mouric0aae732021-01-12 13:32:18 -08002235 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002236
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002237 renderengine::DisplaySettings settings;
2238 settings.physicalDisplay = fullscreenRect();
2239 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002240 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002241
Sally Qi59a9f502021-10-12 18:53:23 +00002242 std::vector<renderengine::LayerSettings> layers;
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002243 renderengine::LayerSettings layer;
2244 layer.geometry.boundaries = fullscreenRect().toFloatRect();
2245 BufferSourceVariant<ForceOpaqueBufferVariant>::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
2246 layer.alpha = 1.0;
Sally Qi59a9f502021-10-12 18:53:23 +00002247 layers.push_back(layer);
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002248
Patrick Williams2e9748f2022-08-09 22:48:18 +00002249 ftl::Future<FenceResult> futureOne =
Alec Mourif29700f2023-08-17 21:53:31 +00002250 mRE->drawLayers(settings, layers, mBuffer, base::unique_fd());
Patrick Williams2e9748f2022-08-09 22:48:18 +00002251 ASSERT_TRUE(futureOne.valid());
2252 auto resultOne = futureOne.get();
2253 ASSERT_TRUE(resultOne.ok());
2254 auto fenceOne = resultOne.value();
Sally Qi4cabdd02021-08-05 16:45:57 -07002255
Patrick Williams2e9748f2022-08-09 22:48:18 +00002256 ftl::Future<FenceResult> futureTwo =
Alec Mourif29700f2023-08-17 21:53:31 +00002257 mRE->drawLayers(settings, layers, mBuffer, base::unique_fd(fenceOne->dup()));
Patrick Williams2e9748f2022-08-09 22:48:18 +00002258 ASSERT_TRUE(futureTwo.valid());
2259 auto resultTwo = futureTwo.get();
2260 ASSERT_TRUE(resultTwo.ok());
2261 auto fenceTwo = resultTwo.value();
2262 fenceTwo->waitForever(LOG_TAG);
Derek Sollenbergerec411212021-08-25 10:54:47 -04002263
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002264 // Only cleanup the first time.
Ian Elliott1f0911e2022-09-09 16:31:47 -06002265 if (mRE->canSkipPostRenderCleanup()) {
2266 // Skia's Vk backend may keep the texture alive beyond drawLayersInternal, so
2267 // it never gets added to the cleanup list. In those cases, we can skip.
Leon Scroggins III696bf932024-01-24 15:21:05 -05002268 EXPECT_TRUE(GetParam()->graphicsApi() == renderengine::RenderEngine::GraphicsApi::VK);
Ian Elliott1f0911e2022-09-09 16:31:47 -06002269 } else {
2270 mRE->cleanupPostRender();
2271 EXPECT_TRUE(mRE->canSkipPostRenderCleanup());
2272 }
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002273}
2274
Ana Krulecf9a15d92020-12-11 08:35:00 -08002275TEST_P(RenderEngineTest, testRoundedCornersCrop) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002276 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002277 GTEST_SKIP();
2278 }
Alec Mouric0aae732021-01-12 13:32:18 -08002279 initializeRenderEngine();
Ana Krulecf9a15d92020-12-11 08:35:00 -08002280
2281 renderengine::DisplaySettings settings;
2282 settings.physicalDisplay = fullscreenRect();
2283 settings.clip = fullscreenRect();
2284 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2285
Sally Qi59a9f502021-10-12 18:53:23 +00002286 std::vector<renderengine::LayerSettings> layers;
Ana Krulecf9a15d92020-12-11 08:35:00 -08002287
2288 renderengine::LayerSettings redLayer;
2289 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2290 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002291 redLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
2292
Ana Krulecf9a15d92020-12-11 08:35:00 -08002293 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2294 // Red background.
2295 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2296 redLayer.alpha = 1.0f;
2297
Sally Qi59a9f502021-10-12 18:53:23 +00002298 layers.push_back(redLayer);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002299
2300 // Green layer with 1/3 size.
2301 renderengine::LayerSettings greenLayer;
2302 greenLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2303 greenLayer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002304 greenLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
Ana Krulecf9a15d92020-12-11 08:35:00 -08002305 // Bottom right corner is not going to be rounded.
2306 greenLayer.geometry.roundedCornersCrop =
2307 Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3, DEFAULT_DISPLAY_HEIGHT,
2308 DEFAULT_DISPLAY_HEIGHT)
2309 .toFloatRect();
2310 greenLayer.source.solidColor = half3(0.0f, 1.0f, 0.0f);
2311 greenLayer.alpha = 1.0f;
2312
Sally Qi59a9f502021-10-12 18:53:23 +00002313 layers.push_back(greenLayer);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002314
Alec Mouric0aae732021-01-12 13:32:18 -08002315 invokeDraw(settings, layers);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002316
2317 // Corners should be ignored...
2318 // Screen size: width is 128, height is 256.
2319 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 0);
2320 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, 0, DEFAULT_DISPLAY_WIDTH, 1), 0, 0, 0, 0);
2321 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT - 1, 1, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
2322 // Bottom right corner is kept out of the clipping, and it's green.
2323 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1,
2324 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
2325 0, 255, 0, 255);
2326}
2327
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002328TEST_P(RenderEngineTest, testRoundedCornersParentCrop) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002329 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002330 GTEST_SKIP();
2331 }
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002332 initializeRenderEngine();
2333
2334 renderengine::DisplaySettings settings;
2335 settings.physicalDisplay = fullscreenRect();
2336 settings.clip = fullscreenRect();
2337 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2338
Sally Qi59a9f502021-10-12 18:53:23 +00002339 std::vector<renderengine::LayerSettings> layers;
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002340
2341 renderengine::LayerSettings redLayer;
2342 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2343 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002344 redLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002345 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2346 // Red background.
2347 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2348 redLayer.alpha = 1.0f;
2349
Sally Qi59a9f502021-10-12 18:53:23 +00002350 layers.push_back(redLayer);
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002351
2352 // Green layer with 1/2 size with parent crop rect.
2353 renderengine::LayerSettings greenLayer = redLayer;
2354 greenLayer.geometry.boundaries =
2355 FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT / 2);
2356 greenLayer.source.solidColor = half3(0.0f, 1.0f, 0.0f);
2357
Sally Qi59a9f502021-10-12 18:53:23 +00002358 layers.push_back(greenLayer);
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002359
2360 invokeDraw(settings, layers);
2361
2362 // Due to roundedCornersRadius, the corners are untouched.
2363 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2364 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2365 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2366 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2367
2368 // top middle should be green and the bottom middle red
2369 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, 0), 0, 255, 0, 255);
2370 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0, 255);
2371
2372 // the bottom edge of the green layer should not be rounded
2373 expectBufferColor(Point(0, (DEFAULT_DISPLAY_HEIGHT / 2) - 1), 0, 255, 0, 255);
2374}
2375
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002376TEST_P(RenderEngineTest, testRoundedCornersParentCropSmallBounds) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002377 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002378 GTEST_SKIP();
2379 }
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002380 initializeRenderEngine();
2381
2382 renderengine::DisplaySettings settings;
2383 settings.physicalDisplay = fullscreenRect();
2384 settings.clip = fullscreenRect();
2385 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2386
Sally Qi59a9f502021-10-12 18:53:23 +00002387 std::vector<renderengine::LayerSettings> layers;
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002388
2389 renderengine::LayerSettings redLayer;
2390 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2391 redLayer.geometry.boundaries = FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, 32);
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002392 redLayer.geometry.roundedCornersRadius = {64.0f, 64.0f};
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002393 redLayer.geometry.roundedCornersCrop = FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, 128);
2394 // Red background.
2395 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2396 redLayer.alpha = 1.0f;
2397
Sally Qi59a9f502021-10-12 18:53:23 +00002398 layers.push_back(redLayer);
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002399 invokeDraw(settings, layers);
2400
2401 // Due to roundedCornersRadius, the top corners are untouched.
2402 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2403 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2404
2405 // ensure that the entire height of the red layer was clipped by the rounded corners crop.
2406 expectBufferColor(Point(0, 31), 0, 0, 0, 0);
2407 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 31), 0, 0, 0, 0);
2408
2409 // the bottom middle should be red
2410 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, 31), 255, 0, 0, 255);
2411}
2412
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002413TEST_P(RenderEngineTest, testRoundedCornersXY) {
Leon Scroggins III9ba31e32024-01-25 11:40:26 -05002414 if (!GetParam()->apiSupported()) {
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002415 GTEST_SKIP();
2416 }
2417
2418 initializeRenderEngine();
2419
2420 renderengine::DisplaySettings settings;
2421 settings.physicalDisplay = fullscreenRect();
2422 settings.clip = fullscreenRect();
2423 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2424
2425 std::vector<renderengine::LayerSettings> layers;
2426
2427 renderengine::LayerSettings redLayer;
2428 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2429 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
2430 redLayer.geometry.roundedCornersRadius = {5.0f, 20.0f};
2431 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2432 // Red background.
2433 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2434 redLayer.alpha = 1.0f;
2435
2436 layers.push_back(redLayer);
2437
2438 invokeDraw(settings, layers);
2439
2440 // Due to roundedCornersRadius, the corners are untouched.
2441 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2442 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2443 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2444 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2445
2446 // Y-axis draws a larger radius, check that its untouched as well
2447 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 5), 0, 0, 0, 0);
2448 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 5), 0, 0, 0, 0);
2449 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 5), 0, 0, 0, 0);
2450 expectBufferColor(Point(0, 5), 0, 0, 0, 0);
2451
2452 // middle should be red
2453 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0, 255);
2454}
2455
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002456TEST_P(RenderEngineTest, testClear) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002457 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002458 GTEST_SKIP();
2459 }
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002460 initializeRenderEngine();
2461
2462 const auto rect = fullscreenRect();
2463 const renderengine::DisplaySettings display{
2464 .physicalDisplay = rect,
2465 .clip = rect,
2466 };
2467
2468 const renderengine::LayerSettings redLayer{
2469 .geometry.boundaries = rect.toFloatRect(),
2470 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
2471 .alpha = 1.0f,
2472 };
2473
2474 // This mimics prepareClearClientComposition. This layer should overwrite
2475 // the redLayer, so that the buffer is transparent, rather than red.
2476 const renderengine::LayerSettings clearLayer{
2477 .geometry.boundaries = rect.toFloatRect(),
2478 .source.solidColor = half3(0.0f, 0.0f, 0.0f),
2479 .alpha = 0.0f,
2480 .disableBlending = true,
2481 };
2482
Sally Qi59a9f502021-10-12 18:53:23 +00002483 std::vector<renderengine::LayerSettings> layers{redLayer, clearLayer};
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002484 invokeDraw(display, layers);
2485 expectBufferColor(rect, 0, 0, 0, 0);
2486}
2487
2488TEST_P(RenderEngineTest, testDisableBlendingBuffer) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002489 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002490 GTEST_SKIP();
2491 }
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002492 initializeRenderEngine();
2493
2494 const auto rect = Rect(0, 0, 1, 1);
2495 const renderengine::DisplaySettings display{
2496 .physicalDisplay = rect,
2497 .clip = rect,
2498 };
2499
2500 const renderengine::LayerSettings redLayer{
2501 .geometry.boundaries = rect.toFloatRect(),
2502 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
2503 .alpha = 1.0f,
2504 };
2505
2506 // The next layer will overwrite redLayer with a GraphicBuffer that is green
2507 // applied with a translucent alpha.
Alec Mouria90a5702021-04-16 16:36:21 +00002508 const auto buf = allocateSourceBuffer(1, 1);
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002509 {
2510 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00002511 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2512 reinterpret_cast<void**>(&pixels));
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002513 pixels[0] = 0;
2514 pixels[1] = 255;
2515 pixels[2] = 0;
2516 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00002517 buf->getBuffer()->unlock();
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002518 }
2519
2520 const renderengine::LayerSettings greenLayer{
2521 .geometry.boundaries = rect.toFloatRect(),
2522 .source =
2523 renderengine::PixelSource{
2524 .buffer =
2525 renderengine::Buffer{
2526 .buffer = buf,
2527 .usePremultipliedAlpha = true,
2528 },
2529 },
2530 .alpha = 0.5f,
2531 .disableBlending = true,
2532 };
2533
Sally Qi59a9f502021-10-12 18:53:23 +00002534 std::vector<renderengine::LayerSettings> layers{redLayer, greenLayer};
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002535 invokeDraw(display, layers);
2536 expectBufferColor(rect, 0, 128, 0, 128);
2537}
2538
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002539TEST_P(RenderEngineTest, testDimming) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002540 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002541 GTEST_SKIP();
2542 }
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002543 initializeRenderEngine();
2544
Alec Mouri85065692022-03-18 00:58:26 +00002545 const ui::Dataspace dataspace = ui::Dataspace::V0_SRGB_LINEAR;
2546
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002547 const auto displayRect = Rect(3, 1);
2548 const renderengine::DisplaySettings display{
2549 .physicalDisplay = displayRect,
2550 .clip = displayRect,
Alec Mouri85065692022-03-18 00:58:26 +00002551 .outputDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002552 .targetLuminanceNits = 1000.f,
2553 };
2554
2555 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2556 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2557 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2558
2559 const renderengine::LayerSettings greenLayer{
2560 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2561 .source =
2562 renderengine::PixelSource{
2563 .buffer =
2564 renderengine::Buffer{
2565 .buffer = greenBuffer,
2566 .usePremultipliedAlpha = true,
2567 },
2568 },
2569 .alpha = 1.0f,
Alec Mouri85065692022-03-18 00:58:26 +00002570 .sourceDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002571 .whitePointNits = 200.f,
2572 };
2573
2574 const renderengine::LayerSettings blueLayer{
2575 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2576 .source =
2577 renderengine::PixelSource{
2578 .buffer =
2579 renderengine::Buffer{
2580 .buffer = blueBuffer,
2581 .usePremultipliedAlpha = true,
2582 },
2583 },
2584 .alpha = 1.0f,
Alec Mouri85065692022-03-18 00:58:26 +00002585 .sourceDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002586 .whitePointNits = 1000.f / 51.f,
2587 };
2588
2589 const renderengine::LayerSettings redLayer{
2590 .geometry.boundaries = FloatRect(2.f, 0.f, 3.f, 1.f),
2591 .source =
2592 renderengine::PixelSource{
2593 .buffer =
2594 renderengine::Buffer{
2595 .buffer = redBuffer,
2596 .usePremultipliedAlpha = true,
2597 },
2598 },
2599 .alpha = 1.0f,
Alec Mouri85065692022-03-18 00:58:26 +00002600 .sourceDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002601 // When the white point is not set for a layer, just ignore it and treat it as the same
2602 // as the max layer
2603 .whitePointNits = -1.f,
2604 };
2605
2606 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer, redLayer};
2607 invokeDraw(display, layers);
2608
2609 expectBufferColor(Rect(1, 1), 0, 51, 0, 255, 1);
2610 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 5, 255, 1);
2611 expectBufferColor(Rect(2, 0, 3, 1), 51, 0, 0, 255, 1);
2612}
2613
Alec Mouri85065692022-03-18 00:58:26 +00002614TEST_P(RenderEngineTest, testDimming_inGammaSpace) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002615 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002616 GTEST_SKIP();
2617 }
Alec Mouri85065692022-03-18 00:58:26 +00002618 initializeRenderEngine();
2619
2620 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2621 ui::Dataspace::TRANSFER_GAMMA2_2 |
2622 ui::Dataspace::RANGE_FULL);
2623
2624 const auto displayRect = Rect(3, 1);
2625 const renderengine::DisplaySettings display{
2626 .physicalDisplay = displayRect,
2627 .clip = displayRect,
2628 .outputDataspace = dataspace,
2629 .targetLuminanceNits = 1000.f,
2630 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2631 };
2632
2633 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2634 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2635 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2636
2637 const renderengine::LayerSettings greenLayer{
2638 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2639 .source =
2640 renderengine::PixelSource{
2641 .buffer =
2642 renderengine::Buffer{
2643 .buffer = greenBuffer,
2644 .usePremultipliedAlpha = true,
2645 },
2646 },
2647 .alpha = 1.0f,
2648 .sourceDataspace = dataspace,
2649 .whitePointNits = 200.f,
2650 };
2651
2652 const renderengine::LayerSettings blueLayer{
2653 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2654 .source =
2655 renderengine::PixelSource{
2656 .buffer =
2657 renderengine::Buffer{
2658 .buffer = blueBuffer,
2659 .usePremultipliedAlpha = true,
2660 },
2661 },
2662 .alpha = 1.0f,
2663 .sourceDataspace = dataspace,
2664 .whitePointNits = 1000.f / 51.f,
2665 };
2666
2667 const renderengine::LayerSettings redLayer{
2668 .geometry.boundaries = FloatRect(2.f, 0.f, 3.f, 1.f),
2669 .source =
2670 renderengine::PixelSource{
2671 .buffer =
2672 renderengine::Buffer{
2673 .buffer = redBuffer,
2674 .usePremultipliedAlpha = true,
2675 },
2676 },
2677 .alpha = 1.0f,
2678 .sourceDataspace = dataspace,
2679 // When the white point is not set for a layer, just ignore it and treat it as the same
2680 // as the max layer
2681 .whitePointNits = -1.f,
2682 };
2683
2684 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer, redLayer};
2685 invokeDraw(display, layers);
2686
2687 expectBufferColor(Rect(1, 1), 0, 122, 0, 255, 1);
2688 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 42, 255, 1);
2689 expectBufferColor(Rect(2, 0, 3, 1), 122, 0, 0, 255, 1);
2690}
2691
Alec Mouri9bcd1d12022-04-21 22:16:56 +00002692TEST_P(RenderEngineTest, testDimming_inGammaSpace_withDisplayColorTransform) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002693 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002694 GTEST_SKIP();
2695 }
Alec Mouri9bcd1d12022-04-21 22:16:56 +00002696 initializeRenderEngine();
2697
2698 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2699 ui::Dataspace::TRANSFER_GAMMA2_2 |
2700 ui::Dataspace::RANGE_FULL);
2701
2702 const auto displayRect = Rect(3, 1);
2703 const renderengine::DisplaySettings display{
2704 .physicalDisplay = displayRect,
2705 .clip = displayRect,
2706 .outputDataspace = dataspace,
2707 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
2708 .targetLuminanceNits = 1000.f,
2709 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2710 };
2711
2712 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2713 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2714 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2715
2716 const renderengine::LayerSettings greenLayer{
2717 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2718 .source =
2719 renderengine::PixelSource{
2720 .buffer =
2721 renderengine::Buffer{
2722 .buffer = greenBuffer,
2723 .usePremultipliedAlpha = true,
2724 },
2725 },
2726 .alpha = 1.0f,
2727 .sourceDataspace = dataspace,
2728 .whitePointNits = 200.f,
2729 };
2730
2731 const renderengine::LayerSettings redLayer{
2732 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2733 .source =
2734 renderengine::PixelSource{
2735 .buffer =
2736 renderengine::Buffer{
2737 .buffer = redBuffer,
2738 .usePremultipliedAlpha = true,
2739 },
2740 },
2741 .alpha = 1.0f,
2742 .sourceDataspace = dataspace,
2743 // When the white point is not set for a layer, just ignore it and treat it as the same
2744 // as the max layer
2745 .whitePointNits = -1.f,
2746 };
2747
2748 std::vector<renderengine::LayerSettings> layers{greenLayer, redLayer};
2749 invokeDraw(display, layers);
2750
2751 expectBufferColor(Rect(1, 1), 0, 0, 0, 255, 1);
2752 expectBufferColor(Rect(1, 0, 2, 1), 0, 122, 0, 255, 1);
2753}
2754
2755TEST_P(RenderEngineTest, testDimming_inGammaSpace_withDisplayColorTransform_deviceHandles) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002756 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002757 GTEST_SKIP();
2758 }
Alec Mouri9bcd1d12022-04-21 22:16:56 +00002759 initializeRenderEngine();
2760
2761 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2762 ui::Dataspace::TRANSFER_GAMMA2_2 |
2763 ui::Dataspace::RANGE_FULL);
2764
2765 const auto displayRect = Rect(3, 1);
2766 const renderengine::DisplaySettings display{
2767 .physicalDisplay = displayRect,
2768 .clip = displayRect,
2769 .outputDataspace = dataspace,
2770 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
2771 .deviceHandlesColorTransform = true,
2772 .targetLuminanceNits = 1000.f,
2773 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2774 };
2775
2776 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2777 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2778 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2779
2780 const renderengine::LayerSettings greenLayer{
2781 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2782 .source =
2783 renderengine::PixelSource{
2784 .buffer =
2785 renderengine::Buffer{
2786 .buffer = greenBuffer,
2787 .usePremultipliedAlpha = true,
2788 },
2789 },
2790 .alpha = 1.0f,
2791 .sourceDataspace = dataspace,
2792 .whitePointNits = 200.f,
2793 };
2794
2795 const renderengine::LayerSettings redLayer{
2796 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2797 .source =
2798 renderengine::PixelSource{
2799 .buffer =
2800 renderengine::Buffer{
2801 .buffer = redBuffer,
2802 .usePremultipliedAlpha = true,
2803 },
2804 },
2805 .alpha = 1.0f,
2806 .sourceDataspace = dataspace,
2807 // When the white point is not set for a layer, just ignore it and treat it as the same
2808 // as the max layer
2809 .whitePointNits = -1.f,
2810 };
2811
2812 std::vector<renderengine::LayerSettings> layers{greenLayer, redLayer};
2813 invokeDraw(display, layers);
2814
2815 expectBufferColor(Rect(1, 1), 0, 122, 0, 255, 1);
2816 expectBufferColor(Rect(1, 0, 2, 1), 122, 0, 0, 255, 1);
2817}
2818
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002819TEST_P(RenderEngineTest, testDimming_withoutTargetLuminance) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002820 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002821 GTEST_SKIP();
2822 }
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002823 initializeRenderEngine();
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002824
2825 const auto displayRect = Rect(2, 1);
2826 const renderengine::DisplaySettings display{
2827 .physicalDisplay = displayRect,
2828 .clip = displayRect,
2829 .outputDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2830 .targetLuminanceNits = -1.f,
2831 };
2832
2833 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2834 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2835
2836 const renderengine::LayerSettings greenLayer{
2837 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2838 .source =
2839 renderengine::PixelSource{
2840 .buffer =
2841 renderengine::Buffer{
2842 .buffer = greenBuffer,
2843 .usePremultipliedAlpha = true,
2844 },
2845 },
2846 .alpha = 1.0f,
2847 .sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2848 .whitePointNits = 200.f,
2849 };
2850
2851 const renderengine::LayerSettings blueLayer{
2852 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2853 .source =
2854 renderengine::PixelSource{
2855 .buffer =
2856 renderengine::Buffer{
2857 .buffer = blueBuffer,
2858 .usePremultipliedAlpha = true,
2859 },
2860 },
2861 .alpha = 1.0f,
2862 .sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2863 .whitePointNits = 1000.f,
2864 };
2865
2866 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer};
2867 invokeDraw(display, layers);
2868
2869 expectBufferColor(Rect(1, 1), 0, 51, 0, 255, 1);
2870 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 255, 255);
2871}
2872
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002873TEST_P(RenderEngineTest, test_isOpaque) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002874 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002875 GTEST_SKIP();
2876 }
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002877 initializeRenderEngine();
2878
2879 const auto rect = Rect(0, 0, 1, 1);
2880 const renderengine::DisplaySettings display{
2881 .physicalDisplay = rect,
2882 .clip = rect,
2883 .outputDataspace = ui::Dataspace::DISPLAY_P3,
2884 };
2885
2886 // Create an unpremul buffer that is green with no alpha. Using isOpaque
2887 // should make the green show.
2888 const auto buf = allocateSourceBuffer(1, 1);
2889 {
2890 uint8_t* pixels;
2891 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2892 reinterpret_cast<void**>(&pixels));
2893 pixels[0] = 0;
2894 pixels[1] = 255;
2895 pixels[2] = 0;
2896 pixels[3] = 0;
2897 buf->getBuffer()->unlock();
2898 }
2899
2900 const renderengine::LayerSettings greenLayer{
2901 .geometry.boundaries = rect.toFloatRect(),
2902 .source =
2903 renderengine::PixelSource{
2904 .buffer =
2905 renderengine::Buffer{
2906 .buffer = buf,
2907 // Although the pixels are not
2908 // premultiplied in practice, this
2909 // matches the input we see.
2910 .usePremultipliedAlpha = true,
2911 .isOpaque = true,
2912 },
2913 },
2914 .alpha = 1.0f,
2915 };
2916
Sally Qi59a9f502021-10-12 18:53:23 +00002917 std::vector<renderengine::LayerSettings> layers{greenLayer};
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002918 invokeDraw(display, layers);
2919
Alec Mouri47bcb072023-08-15 02:02:49 +00002920 expectBufferColor(rect, 117, 251, 76, 255);
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002921}
Alec Mouri4049b532021-10-15 20:59:33 -07002922
Alec Mouri4049b532021-10-15 20:59:33 -07002923TEST_P(RenderEngineTest, test_tonemapPQMatches) {
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 Mouri4049b532021-10-15 20:59:33 -07002928 initializeRenderEngine();
2929
Alec Mouri5a493722022-01-26 16:43:02 -08002930 tonemap(
2931 static_cast<ui::Dataspace>(HAL_DATASPACE_STANDARD_BT2020 |
2932 HAL_DATASPACE_TRANSFER_ST2084 | HAL_DATASPACE_RANGE_FULL),
2933 [](vec3 color) { return EOTF_PQ(color); },
2934 [](vec3 color, float) {
2935 static constexpr float kMaxPQLuminance = 10000.f;
2936 return color * kMaxPQLuminance;
2937 });
2938}
Alec Mouri4049b532021-10-15 20:59:33 -07002939
Alec Mouri5a493722022-01-26 16:43:02 -08002940TEST_P(RenderEngineTest, test_tonemapHLGMatches) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002941 if (!GetParam()->apiSupported()) {
Alec Mouri5a493722022-01-26 16:43:02 -08002942 GTEST_SKIP();
Alec Mouri4049b532021-10-15 20:59:33 -07002943 }
2944
Alec Mouri5a493722022-01-26 16:43:02 -08002945 initializeRenderEngine();
Alec Mouri4049b532021-10-15 20:59:33 -07002946
Alec Mouri5a493722022-01-26 16:43:02 -08002947 tonemap(
2948 static_cast<ui::Dataspace>(HAL_DATASPACE_STANDARD_BT2020 | HAL_DATASPACE_TRANSFER_HLG |
2949 HAL_DATASPACE_RANGE_FULL),
2950 [](vec3 color) { return EOTF_HLG(color); },
2951 [](vec3 color, float currentLuminaceNits) {
2952 static constexpr float kMaxHLGLuminance = 1000.f;
Alec Mouri7a577452022-03-04 23:41:38 +00002953 return color * kMaxHLGLuminance;
Alec Mouri5a493722022-01-26 16:43:02 -08002954 });
Alec Mouri4049b532021-10-15 20:59:33 -07002955}
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -05002956
2957TEST_P(RenderEngineTest, r8_behaves_as_mask) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002958 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002959 GTEST_SKIP();
2960 }
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -05002961 initializeRenderEngine();
2962
2963 const auto r8Buffer = allocateR8Buffer(2, 1);
2964 if (!r8Buffer) {
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05002965 GTEST_SKIP() << "Test is only necessary on devices that support r8";
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -05002966 return;
2967 }
2968 {
2969 uint8_t* pixels;
2970 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2971 reinterpret_cast<void**>(&pixels));
2972 // This will be drawn on top of a green buffer. We'll verify that 255
2973 // results in keeping the original green and 0 results in black.
2974 pixels[0] = 0;
2975 pixels[1] = 255;
2976 r8Buffer->getBuffer()->unlock();
2977 }
2978
2979 const auto rect = Rect(0, 0, 2, 1);
2980 const renderengine::DisplaySettings display{
2981 .physicalDisplay = rect,
2982 .clip = rect,
2983 .outputDataspace = ui::Dataspace::SRGB,
2984 };
2985
2986 const auto greenBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(0, 255, 0, 255));
2987 const renderengine::LayerSettings greenLayer{
2988 .geometry.boundaries = rect.toFloatRect(),
2989 .source =
2990 renderengine::PixelSource{
2991 .buffer =
2992 renderengine::Buffer{
2993 .buffer = greenBuffer,
2994 },
2995 },
2996 .alpha = 1.0f,
2997 };
2998 const renderengine::LayerSettings r8Layer{
2999 .geometry.boundaries = rect.toFloatRect(),
3000 .source =
3001 renderengine::PixelSource{
3002 .buffer =
3003 renderengine::Buffer{
3004 .buffer = r8Buffer,
3005 },
3006 },
3007 .alpha = 1.0f,
3008 };
3009
3010 std::vector<renderengine::LayerSettings> layers{greenLayer, r8Layer};
3011 invokeDraw(display, layers);
3012
3013 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 255);
3014 expectBufferColor(Rect(1, 0, 2, 1), 0, 255, 0, 255);
3015}
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003016
3017TEST_P(RenderEngineTest, r8_respects_color_transform) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05003018 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003019 GTEST_SKIP();
3020 }
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003021 initializeRenderEngine();
3022
3023 const auto r8Buffer = allocateR8Buffer(2, 1);
3024 if (!r8Buffer) {
3025 GTEST_SKIP() << "Test is only necessary on devices that support r8";
3026 return;
3027 }
3028 {
3029 uint8_t* pixels;
3030 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
3031 reinterpret_cast<void**>(&pixels));
3032 pixels[0] = 0;
3033 pixels[1] = 255;
3034 r8Buffer->getBuffer()->unlock();
3035 }
3036
3037 const auto rect = Rect(0, 0, 2, 1);
3038 const renderengine::DisplaySettings display{
3039 .physicalDisplay = rect,
3040 .clip = rect,
3041 .outputDataspace = ui::Dataspace::SRGB,
3042 // Verify that the R8 layer respects the color transform when
3043 // deviceHandlesColorTransform is false. This transform converts
3044 // pure red to pure green. That will occur when the R8 buffer is
3045 // 255. When the R8 buffer is 0, it will still change to black, as
3046 // with r8_behaves_as_mask.
Alec Mouri9bcd1d12022-04-21 22:16:56 +00003047 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003048 .deviceHandlesColorTransform = false,
3049 };
3050
3051 const auto redBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(255, 0, 0, 255));
3052 const renderengine::LayerSettings redLayer{
3053 .geometry.boundaries = rect.toFloatRect(),
3054 .source =
3055 renderengine::PixelSource{
3056 .buffer =
3057 renderengine::Buffer{
3058 .buffer = redBuffer,
3059 },
3060 },
3061 .alpha = 1.0f,
3062 };
3063 const renderengine::LayerSettings r8Layer{
3064 .geometry.boundaries = rect.toFloatRect(),
3065 .source =
3066 renderengine::PixelSource{
3067 .buffer =
3068 renderengine::Buffer{
3069 .buffer = r8Buffer,
3070 },
3071 },
3072 .alpha = 1.0f,
3073 };
3074
3075 std::vector<renderengine::LayerSettings> layers{redLayer, r8Layer};
3076 invokeDraw(display, layers);
3077
3078 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 255);
3079 expectBufferColor(Rect(1, 0, 2, 1), 0, 255, 0, 255);
3080}
3081
3082TEST_P(RenderEngineTest, r8_respects_color_transform_when_device_handles) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05003083 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003084 GTEST_SKIP();
3085 }
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003086 initializeRenderEngine();
3087
3088 const auto r8Buffer = allocateR8Buffer(2, 1);
3089 if (!r8Buffer) {
3090 GTEST_SKIP() << "Test is only necessary on devices that support r8";
3091 return;
3092 }
3093 {
3094 uint8_t* pixels;
3095 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
3096 reinterpret_cast<void**>(&pixels));
3097 pixels[0] = 0;
3098 pixels[1] = 255;
3099 r8Buffer->getBuffer()->unlock();
3100 }
3101
3102 const auto rect = Rect(0, 0, 2, 1);
3103 const renderengine::DisplaySettings display{
3104 .physicalDisplay = rect,
3105 .clip = rect,
3106 .outputDataspace = ui::Dataspace::SRGB,
3107 // If deviceHandlesColorTransform is true, pixels where the A8
3108 // buffer is opaque are unaffected. If the colorTransform is
3109 // invertible, pixels where the A8 buffer are transparent have the
3110 // inverse applied to them so that the DPU will convert them back to
3111 // black. Test with an arbitrary, invertible matrix.
3112 .colorTransform = mat4(1, 0, 0, 2,
3113 3, 1, 2, 5,
3114 0, 5, 3, 0,
3115 0, 1, 0, 2),
3116 .deviceHandlesColorTransform = true,
3117 };
3118
3119 const auto redBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(255, 0, 0, 255));
3120 const renderengine::LayerSettings redLayer{
3121 .geometry.boundaries = rect.toFloatRect(),
3122 .source =
3123 renderengine::PixelSource{
3124 .buffer =
3125 renderengine::Buffer{
3126 .buffer = redBuffer,
3127 },
3128 },
3129 .alpha = 1.0f,
3130 };
3131 const renderengine::LayerSettings r8Layer{
3132 .geometry.boundaries = rect.toFloatRect(),
3133 .source =
3134 renderengine::PixelSource{
3135 .buffer =
3136 renderengine::Buffer{
3137 .buffer = r8Buffer,
3138 },
3139 },
3140 .alpha = 1.0f,
3141 };
3142
3143 std::vector<renderengine::LayerSettings> layers{redLayer, r8Layer};
3144 invokeDraw(display, layers);
3145
3146 expectBufferColor(Rect(1, 0, 2, 1), 255, 0, 0, 255); // Still red.
3147 expectBufferColor(Rect(0, 0, 1, 1), 0, 70, 0, 255);
3148}
Leon Scroggins III45be9182022-04-27 10:37:11 -04003149
3150TEST_P(RenderEngineTest, primeShaderCache) {
Nolan Scobie195631a2024-03-26 12:22:23 -04003151 // TODO: b/331447071 - Fix in Graphite and re-enable.
3152 if (GetParam()->skiaBackend() == renderengine::RenderEngine::SkiaBackend::GRAPHITE) {
3153 GTEST_SKIP();
3154 }
3155
Leon Scroggins III696bf932024-01-24 15:21:05 -05003156 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003157 GTEST_SKIP();
3158 }
Leon Scroggins III45be9182022-04-27 10:37:11 -04003159 initializeRenderEngine();
3160
Russell Myers3348c742024-04-29 20:22:42 +00003161 PrimeCacheConfig config;
3162 config.cacheUltraHDR = false;
3163 auto fut = mRE->primeCache(config);
Leon Scroggins III45be9182022-04-27 10:37:11 -04003164 if (fut.valid()) {
3165 fut.wait();
3166 }
3167
Alec Mouri47bcb072023-08-15 02:02:49 +00003168 static constexpr int kMinimumExpectedShadersCompiled = 60;
Leon Scroggins III45be9182022-04-27 10:37:11 -04003169 ASSERT_GT(static_cast<skia::SkiaGLRenderEngine*>(mRE.get())->reportShadersCompiled(),
Alec Mouri47bcb072023-08-15 02:02:49 +00003170 kMinimumExpectedShadersCompiled);
Leon Scroggins III45be9182022-04-27 10:37:11 -04003171}
Derek Sollenbergerd3f60652021-06-11 15:34:36 -04003172} // namespace renderengine
Alec Mouri6e57f682018-09-29 20:45:08 -07003173} // namespace android
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08003174
3175// TODO(b/129481165): remove the #pragma below and fix conversion issues
Marin Shalamanovbed7fd32020-12-21 20:02:20 +01003176#pragma clang diagnostic pop // ignored "-Wconversion -Wextra"