blob: b5cc65f27d3d6819a829444bd29b5d6f7cce15d7 [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
Nolan Scobiebe6f9e82024-06-27 17:04:12 -040037#include <algorithm>
Alec Mouric0aae732021-01-12 13:32:18 -080038#include <chrono>
39#include <condition_variable>
Nolan Scobiebe6f9e82024-06-27 17:04:12 -040040#include <filesystem>
Alec Mouric0aae732021-01-12 13:32:18 -080041#include <fstream>
Nolan Scobiebe6f9e82024-06-27 17:04:12 -040042#include <system_error>
Alec Mouric0aae732021-01-12 13:32:18 -080043
Alec Mouric0aae732021-01-12 13:32:18 -080044#include "../skia/SkiaGLRenderEngine.h"
Ian Elliott1f0911e2022-09-09 16:31:47 -060045#include "../skia/SkiaVkRenderEngine.h"
Ana Krulec9bc9dc62020-02-26 12:16:40 -080046#include "../threaded/RenderEngineThreaded.h"
Alec Mouri6e57f682018-09-29 20:45:08 -070047
Nolan Scobie488101b2024-05-20 13:32:13 -040048// TODO: b/341728634 - Clean up conditional compilation.
49#if COM_ANDROID_GRAPHICS_SURFACEFLINGER_FLAGS(GRAPHITE_RENDERENGINE) || \
50 COM_ANDROID_GRAPHICS_SURFACEFLINGER_FLAGS(FORCE_COMPILE_GRAPHITE_RENDERENGINE)
51#define COMPILE_GRAPHITE_RENDERENGINE 1
52#else
53#define COMPILE_GRAPHITE_RENDERENGINE 0
54#endif
55
Alec Mouri1089aed2018-10-25 21:33:57 -070056constexpr int DEFAULT_DISPLAY_WIDTH = 128;
57constexpr int DEFAULT_DISPLAY_HEIGHT = 256;
58constexpr int DEFAULT_DISPLAY_OFFSET = 64;
Vishnu Nair16efdbf2019-12-10 11:55:42 -080059constexpr bool WRITE_BUFFER_TO_FILE_ON_FAILURE = false;
Alec Mouri1089aed2018-10-25 21:33:57 -070060
Alec Mouri6e57f682018-09-29 20:45:08 -070061namespace android {
Derek Sollenbergerd3f60652021-06-11 15:34:36 -040062namespace renderengine {
Alec Mouri6e57f682018-09-29 20:45:08 -070063
Alec Mouri5a493722022-01-26 16:43:02 -080064namespace {
65
66double EOTF_PQ(double channel) {
67 float m1 = (2610.0 / 4096.0) / 4.0;
68 float m2 = (2523.0 / 4096.0) * 128.0;
69 float c1 = (3424.0 / 4096.0);
70 float c2 = (2413.0 / 4096.0) * 32.0;
71 float c3 = (2392.0 / 4096.0) * 32.0;
72
73 float tmp = std::pow(std::clamp(channel, 0.0, 1.0), 1.0 / m2);
74 tmp = std::fmax(tmp - c1, 0.0) / (c2 - c3 * tmp);
75 return std::pow(tmp, 1.0 / m1);
76}
77
78vec3 EOTF_PQ(vec3 color) {
79 return vec3(EOTF_PQ(color.r), EOTF_PQ(color.g), EOTF_PQ(color.b));
80}
81
82double EOTF_HLG(double channel) {
83 const float a = 0.17883277;
84 const float b = 0.28466892;
85 const float c = 0.55991073;
86 return channel <= 0.5 ? channel * channel / 3.0 : (exp((channel - c) / a) + b) / 12.0;
87}
88
89vec3 EOTF_HLG(vec3 color) {
90 return vec3(EOTF_HLG(color.r), EOTF_HLG(color.g), EOTF_HLG(color.b));
91}
92
93double OETF_sRGB(double channel) {
94 return channel <= 0.0031308 ? channel * 12.92 : (pow(channel, 1.0 / 2.4) * 1.055) - 0.055;
95}
96
97int sign(float in) {
98 return in >= 0.0 ? 1 : -1;
99}
100
101vec3 OETF_sRGB(vec3 linear) {
102 return vec3(sign(linear.r) * OETF_sRGB(linear.r), sign(linear.g) * OETF_sRGB(linear.g),
103 sign(linear.b) * OETF_sRGB(linear.b));
104}
105
Alec Mouri9bcd1d12022-04-21 22:16:56 +0000106// clang-format off
107// Converts red channels to green channels, and zeroes out an existing green channel.
108static const auto kRemoveGreenAndMoveRedToGreenMat4 = mat4(0, 1, 0, 0,
109 0, 0, 0, 0,
110 0, 0, 1, 0,
111 0, 0, 0, 1);
112// clang-format on
113
Alec Mouri5a493722022-01-26 16:43:02 -0800114} // namespace
115
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800116class RenderEngineFactory {
117public:
118 virtual ~RenderEngineFactory() = default;
119
120 virtual std::string name() = 0;
Leon Scroggins III696bf932024-01-24 15:21:05 -0500121 virtual renderengine::RenderEngine::GraphicsApi graphicsApi() = 0;
Nolan Scobie195631a2024-03-26 12:22:23 -0400122 virtual renderengine::RenderEngine::SkiaBackend skiaBackend() = 0;
Leon Scroggins IIIf3369ed2024-02-16 17:52:42 -0500123 bool apiSupported() { return renderengine::RenderEngine::canSupport(graphicsApi()); }
Leon Scroggins III5ef55002024-01-25 10:51:45 -0500124 std::unique_ptr<renderengine::RenderEngine> createRenderEngine() {
125 renderengine::RenderEngineCreationArgs reCreationArgs =
126 renderengine::RenderEngineCreationArgs::Builder()
127 .setPixelFormat(static_cast<int>(ui::PixelFormat::RGBA_8888))
128 .setImageCacheSize(1)
129 .setEnableProtectedContext(false)
130 .setPrecacheToneMapperShaderOnly(false)
Robin Lee7338bd92024-04-04 14:05:07 +0000131 .setBlurAlgorithm(renderengine::RenderEngine::BlurAlgorithm::KAWASE)
Leon Scroggins III5ef55002024-01-25 10:51:45 -0500132 .setContextPriority(renderengine::RenderEngine::ContextPriority::MEDIUM)
Leon Scroggins III696bf932024-01-24 15:21:05 -0500133 .setThreaded(renderengine::RenderEngine::Threaded::NO)
134 .setGraphicsApi(graphicsApi())
Nolan Scobie195631a2024-03-26 12:22:23 -0400135 .setSkiaBackend(skiaBackend())
Leon Scroggins III5ef55002024-01-25 10:51:45 -0500136 .build();
137 return renderengine::RenderEngine::create(reCreationArgs);
138 }
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800139};
140
Alec Mouri0eab3e82020-12-08 18:10:27 -0800141class SkiaGLESRenderEngineFactory : public RenderEngineFactory {
142public:
Alec Mouric0aae732021-01-12 13:32:18 -0800143 std::string name() override { return "SkiaGLRenderEngineFactory"; }
Alec Mouri0eab3e82020-12-08 18:10:27 -0800144
Leon Scroggins III696bf932024-01-24 15:21:05 -0500145 renderengine::RenderEngine::GraphicsApi graphicsApi() {
146 return renderengine::RenderEngine::GraphicsApi::GL;
Alec Mouric0aae732021-01-12 13:32:18 -0800147 }
Nolan Scobie195631a2024-03-26 12:22:23 -0400148
149 renderengine::RenderEngine::SkiaBackend skiaBackend() override {
150 return renderengine::RenderEngine::SkiaBackend::GANESH;
151 }
152};
153
154class GaneshVkRenderEngineFactory : public RenderEngineFactory {
155public:
156 std::string name() override { return "GaneshVkRenderEngineFactory"; }
157
158 renderengine::RenderEngine::GraphicsApi graphicsApi() override {
159 return renderengine::RenderEngine::GraphicsApi::VK;
160 }
161
162 renderengine::RenderEngine::SkiaBackend skiaBackend() override {
163 return renderengine::RenderEngine::SkiaBackend::GANESH;
164 }
165};
166
Nolan Scobie488101b2024-05-20 13:32:13 -0400167// TODO: b/341728634 - Clean up conditional compilation.
168#if COMPILE_GRAPHITE_RENDERENGINE
Nolan Scobie195631a2024-03-26 12:22:23 -0400169class GraphiteVkRenderEngineFactory : public RenderEngineFactory {
170public:
171 std::string name() override { return "GraphiteVkRenderEngineFactory"; }
172
173 renderengine::RenderEngine::GraphicsApi graphicsApi() override {
174 return renderengine::RenderEngine::GraphicsApi::VK;
175 }
176
177 renderengine::RenderEngine::SkiaBackend skiaBackend() override {
178 return renderengine::RenderEngine::SkiaBackend::GRAPHITE;
179 }
Alec Mouri0eab3e82020-12-08 18:10:27 -0800180};
Nolan Scobie488101b2024-05-20 13:32:13 -0400181#endif
Alec Mouri0eab3e82020-12-08 18:10:27 -0800182
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800183class RenderEngineTest : public ::testing::TestWithParam<std::shared_ptr<RenderEngineFactory>> {
184public:
Alec Mouria90a5702021-04-16 16:36:21 +0000185 std::shared_ptr<renderengine::ExternalTexture> allocateDefaultBuffer() {
186 return std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800187 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -0700188 ExternalTexture>(sp<GraphicBuffer>::
189 make(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT,
190 HAL_PIXEL_FORMAT_RGBA_8888, 1,
191 GRALLOC_USAGE_SW_READ_OFTEN |
192 GRALLOC_USAGE_SW_WRITE_OFTEN |
193 GRALLOC_USAGE_HW_RENDER |
194 GRALLOC_USAGE_HW_TEXTURE,
195 "output"),
Alec Mouria90a5702021-04-16 16:36:21 +0000196 *mRE,
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800197 renderengine::impl::ExternalTexture::Usage::READABLE |
198 renderengine::impl::ExternalTexture::Usage::
199 WRITEABLE);
Alec Mouri6e57f682018-09-29 20:45:08 -0700200 }
201
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800202 // Allocates a 1x1 buffer to fill with a solid color
Alec Mouria90a5702021-04-16 16:36:21 +0000203 std::shared_ptr<renderengine::ExternalTexture> allocateSourceBuffer(uint32_t width,
204 uint32_t height) {
205 return std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800206 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -0700207 ExternalTexture>(sp<GraphicBuffer>::
208 make(width, height, HAL_PIXEL_FORMAT_RGBA_8888, 1,
209 GRALLOC_USAGE_SW_READ_OFTEN |
210 GRALLOC_USAGE_SW_WRITE_OFTEN |
211 GRALLOC_USAGE_HW_TEXTURE,
212 "input"),
Alec Mouria90a5702021-04-16 16:36:21 +0000213 *mRE,
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800214 renderengine::impl::ExternalTexture::Usage::READABLE |
215 renderengine::impl::ExternalTexture::Usage::
216 WRITEABLE);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800217 }
218
Alec Mouricdf6cbc2021-11-01 17:21:15 -0700219 std::shared_ptr<renderengine::ExternalTexture> allocateAndFillSourceBuffer(uint32_t width,
220 uint32_t height,
221 ubyte4 color) {
222 const auto buffer = allocateSourceBuffer(width, height);
223 uint8_t* pixels;
224 buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
225 reinterpret_cast<void**>(&pixels));
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -0500226 for (uint32_t j = 0; j < height; j++) {
227 uint8_t* dst = pixels + (buffer->getBuffer()->getStride() * j * 4);
228 for (uint32_t i = 0; i < width; i++) {
229 dst[0] = color.r;
230 dst[1] = color.g;
231 dst[2] = color.b;
232 dst[3] = color.a;
233 dst += 4;
234 }
235 }
Alec Mouricdf6cbc2021-11-01 17:21:15 -0700236 buffer->getBuffer()->unlock();
237 return buffer;
238 }
239
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -0500240 std::shared_ptr<renderengine::ExternalTexture> allocateR8Buffer(int width, int height) {
Ady Abrahamd11bade2022-08-01 16:18:03 -0700241 const auto kUsageFlags =
242 static_cast<uint64_t>(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
243 GRALLOC_USAGE_HW_TEXTURE);
244 auto buffer =
245 sp<GraphicBuffer>::make(static_cast<uint32_t>(width), static_cast<uint32_t>(height),
246 android::PIXEL_FORMAT_R_8, 1u, kUsageFlags, "r8");
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -0500247 if (buffer->initCheck() != 0) {
248 // Devices are not required to support R8.
249 return nullptr;
250 }
251 return std::make_shared<
252 renderengine::impl::ExternalTexture>(std::move(buffer), *mRE,
253 renderengine::impl::ExternalTexture::Usage::
254 READABLE);
255 }
256
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800257 RenderEngineTest() {
258 const ::testing::TestInfo* const test_info =
259 ::testing::UnitTest::GetInstance()->current_test_info();
Nolan Scobie24a69102024-04-16 18:57:35 +0000260 ALOGI("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800261 }
Alec Mouri1089aed2018-10-25 21:33:57 -0700262
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800263 ~RenderEngineTest() {
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800264 if (WRITE_BUFFER_TO_FILE_ON_FAILURE && ::testing::Test::HasFailure()) {
Nolan Scobiebe6f9e82024-06-27 17:04:12 -0400265 writeBufferToFile("/data/local/tmp/RenderEngineTest/");
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800266 }
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800267 const ::testing::TestInfo* const test_info =
268 ::testing::UnitTest::GetInstance()->current_test_info();
Nolan Scobie24a69102024-04-16 18:57:35 +0000269 ALOGI("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800270 }
271
Nolan Scobiebe6f9e82024-06-27 17:04:12 -0400272 // If called during e.g.
273 // `PerRenderEngineType/RenderEngineTest#drawLayers_fillBufferCheckersRotate90_colorSource/0`
274 // with a directory of `/data/local/tmp/RenderEngineTest`, then mBuffer will be dumped to
275 // `/data/local/tmp/RenderEngineTest/drawLayers_fillBufferCheckersRotate90_colorSource-0.ppm`
276 //
277 // Note: if `directory` does not exist, then its full path will be recursively created with 777
278 // permissions. If `directory` already exists but does not grant the executing user write
279 // permissions, then saving the buffer will fail.
280 //
281 // Since this is test-only code, no security considerations are made.
282 void writeBufferToFile(const filesystem::path& directory) {
283 const auto currentTestInfo = ::testing::UnitTest::GetInstance()->current_test_info();
284 LOG_ALWAYS_FATAL_IF(!currentTestInfo,
285 "writeBufferToFile must be called during execution of a test");
286
287 std::string fileName(currentTestInfo->name());
288 // Test names may include the RenderEngine variant separated by '/', which would separate
289 // the file name into a subdirectory if not corrected.
290 std::replace(fileName.begin(), fileName.end(), '/', '-');
291 fileName.append(".ppm");
292
293 std::error_code err;
294 filesystem::create_directories(directory, err);
295 if (err.value()) {
296 ALOGE("Unable to create directory %s for writing %s (%d: %s)", directory.c_str(),
297 fileName.c_str(), err.value(), err.message().c_str());
298 return;
299 }
300
301 // Append operator ("/") ensures exactly one "/" directly before the argument.
302 const filesystem::path filePath = directory / fileName;
303 std::ofstream file(filePath.c_str(), std::ios::binary);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800304 if (!file.is_open()) {
Nolan Scobiebe6f9e82024-06-27 17:04:12 -0400305 ALOGE("Unable to open file: %s", filePath.c_str());
306 ALOGE("You may need to do: \"adb shell setenforce 0\" to enable surfaceflinger to "
307 "write debug images, or the %s directory might not give the executing user write "
308 "permission",
309 directory.c_str());
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800310 return;
311 }
312
Alec Mouri1089aed2018-10-25 21:33:57 -0700313 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +0000314 mBuffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
315 reinterpret_cast<void**>(&pixels));
Alec Mouri1089aed2018-10-25 21:33:57 -0700316
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800317 file << "P6\n";
Alec Mouria90a5702021-04-16 16:36:21 +0000318 file << mBuffer->getBuffer()->getWidth() << "\n";
319 file << mBuffer->getBuffer()->getHeight() << "\n";
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800320 file << 255 << "\n";
321
Alec Mouria90a5702021-04-16 16:36:21 +0000322 std::vector<uint8_t> outBuffer(mBuffer->getBuffer()->getWidth() *
323 mBuffer->getBuffer()->getHeight() * 3);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800324 auto outPtr = reinterpret_cast<uint8_t*>(outBuffer.data());
325
Alec Mouria90a5702021-04-16 16:36:21 +0000326 for (int32_t j = 0; j < mBuffer->getBuffer()->getHeight(); j++) {
327 const uint8_t* src = pixels + (mBuffer->getBuffer()->getStride() * j) * 4;
328 for (int32_t i = 0; i < mBuffer->getBuffer()->getWidth(); i++) {
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800329 // Only copy R, G and B components
330 outPtr[0] = src[0];
331 outPtr[1] = src[1];
332 outPtr[2] = src[2];
333 outPtr += 3;
334
335 src += 4;
336 }
337 }
338 file.write(reinterpret_cast<char*>(outBuffer.data()), outBuffer.size());
Nolan Scobiebe6f9e82024-06-27 17:04:12 -0400339 ALOGI("Image of incorrect output written to %s", filePath.c_str());
Alec Mouria90a5702021-04-16 16:36:21 +0000340 mBuffer->getBuffer()->unlock();
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800341 }
342
343 void expectBufferColor(const Region& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
344 size_t c;
345 Rect const* rect = region.getArray(&c);
346 for (size_t i = 0; i < c; i++, rect++) {
347 expectBufferColor(*rect, r, g, b, a);
348 }
349 }
350
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -0400351 void expectBufferColor(const Point& point, uint8_t r, uint8_t g, uint8_t b, uint8_t a,
352 uint8_t tolerance = 0) {
353 expectBufferColor(Rect(point.x, point.y, point.x + 1, point.y + 1), r, g, b, a, tolerance);
354 }
355
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800356 void expectBufferColor(const Rect& rect, uint8_t r, uint8_t g, uint8_t b, uint8_t a,
357 uint8_t tolerance = 0) {
Alec Mouri4049b532021-10-15 20:59:33 -0700358 auto generator = [=](Point) { return ubyte4(r, g, b, a); };
359 expectBufferColor(rect, generator, tolerance);
360 }
361
362 using ColorGenerator = std::function<ubyte4(Point location)>;
363
364 void expectBufferColor(const Rect& rect, ColorGenerator generator, uint8_t tolerance = 0) {
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800365 auto colorCompare = [tolerance](const uint8_t* colorA, const uint8_t* colorB) {
366 auto colorBitCompare = [tolerance](uint8_t a, uint8_t b) {
367 uint8_t tmp = a >= b ? a - b : b - a;
368 return tmp <= tolerance;
369 };
370 return std::equal(colorA, colorA + 4, colorB, colorBitCompare);
Alec Mouri1089aed2018-10-25 21:33:57 -0700371 };
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800372
Alec Mouri4049b532021-10-15 20:59:33 -0700373 expectBufferColor(rect, generator, colorCompare);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800374 }
375
Alec Mouri4049b532021-10-15 20:59:33 -0700376 void expectBufferColor(const Rect& region, ColorGenerator generator,
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800377 std::function<bool(const uint8_t* a, const uint8_t* b)> colorCompare) {
378 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +0000379 mBuffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
380 reinterpret_cast<void**>(&pixels));
Alec Mouri1089aed2018-10-25 21:33:57 -0700381 int32_t maxFails = 10;
382 int32_t fails = 0;
383 for (int32_t j = 0; j < region.getHeight(); j++) {
Alec Mouria90a5702021-04-16 16:36:21 +0000384 const uint8_t* src = pixels +
385 (mBuffer->getBuffer()->getStride() * (region.top + j) + region.left) * 4;
Alec Mouri1089aed2018-10-25 21:33:57 -0700386 for (int32_t i = 0; i < region.getWidth(); i++) {
Alec Mouri4049b532021-10-15 20:59:33 -0700387 const auto location = Point(region.left + i, region.top + j);
388 const ubyte4 colors = generator(location);
389 const uint8_t expected[4] = {colors.r, colors.g, colors.b, colors.a};
390 bool colorMatches = colorCompare(src, expected);
391 EXPECT_TRUE(colorMatches)
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -0400392 << GetParam()->name().c_str() << ": "
Alec Mouri4049b532021-10-15 20:59:33 -0700393 << "pixel @ (" << location.x << ", " << location.y << "): "
394 << "expected (" << static_cast<uint32_t>(colors.r) << ", "
395 << static_cast<uint32_t>(colors.g) << ", "
396 << static_cast<uint32_t>(colors.b) << ", "
397 << static_cast<uint32_t>(colors.a) << "), "
Alec Mouri1089aed2018-10-25 21:33:57 -0700398 << "got (" << static_cast<uint32_t>(src[0]) << ", "
399 << static_cast<uint32_t>(src[1]) << ", " << static_cast<uint32_t>(src[2])
400 << ", " << static_cast<uint32_t>(src[3]) << ")";
401 src += 4;
Alec Mouri4049b532021-10-15 20:59:33 -0700402 if (!colorMatches && ++fails >= maxFails) {
Alec Mouri1089aed2018-10-25 21:33:57 -0700403 break;
404 }
405 }
406 if (fails >= maxFails) {
407 break;
408 }
409 }
Alec Mouria90a5702021-04-16 16:36:21 +0000410 mBuffer->getBuffer()->unlock();
Alec Mouri1089aed2018-10-25 21:33:57 -0700411 }
412
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800413 void expectAlpha(const Rect& rect, uint8_t a) {
Alec Mouri4049b532021-10-15 20:59:33 -0700414 auto generator = [=](Point) { return ubyte4(0, 0, 0, a); };
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800415 auto colorCompare = [](const uint8_t* colorA, const uint8_t* colorB) {
416 return colorA[3] == colorB[3];
417 };
Alec Mouri4049b532021-10-15 20:59:33 -0700418 expectBufferColor(rect, generator, colorCompare);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800419 }
420
421 void expectShadowColor(const renderengine::LayerSettings& castingLayer,
Vishnu Naird9e4f462023-10-06 04:05:45 +0000422 const ShadowSettings& shadow, const ubyte4& casterColor,
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800423 const ubyte4& backgroundColor) {
424 const Rect casterRect(castingLayer.geometry.boundaries);
425 Region casterRegion = Region(casterRect);
Vishnu Nair50c0afe2022-07-11 15:04:07 -0700426 const float casterCornerRadius = (castingLayer.geometry.roundedCornersRadius.x +
427 castingLayer.geometry.roundedCornersRadius.y) /
428 2.0;
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800429 if (casterCornerRadius > 0.0f) {
430 // ignore the corners if a corner radius is set
431 Rect cornerRect(casterCornerRadius, casterCornerRadius);
432 casterRegion.subtractSelf(cornerRect.offsetTo(casterRect.left, casterRect.top));
433 casterRegion.subtractSelf(
434 cornerRect.offsetTo(casterRect.right - casterCornerRadius, casterRect.top));
435 casterRegion.subtractSelf(
436 cornerRect.offsetTo(casterRect.left, casterRect.bottom - casterCornerRadius));
437 casterRegion.subtractSelf(cornerRect.offsetTo(casterRect.right - casterCornerRadius,
438 casterRect.bottom - casterCornerRadius));
439 }
440
441 const float shadowInset = shadow.length * -1.0f;
442 const Rect casterWithShadow =
443 Rect(casterRect).inset(shadowInset, shadowInset, shadowInset, shadowInset);
444 const Region shadowRegion = Region(casterWithShadow).subtractSelf(casterRect);
445 const Region backgroundRegion = Region(fullscreenRect()).subtractSelf(casterWithShadow);
446
447 // verify casting layer
448 expectBufferColor(casterRegion, casterColor.r, casterColor.g, casterColor.b, casterColor.a);
449
450 // verify shadows by testing just the alpha since its difficult to validate the shadow color
451 size_t c;
452 Rect const* r = shadowRegion.getArray(&c);
453 for (size_t i = 0; i < c; i++, r++) {
454 expectAlpha(*r, 255);
455 }
456
457 // verify background
458 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
459 backgroundColor.a);
460 }
461
Vishnu Naird9e4f462023-10-06 04:05:45 +0000462 void expectShadowColorWithoutCaster(const FloatRect& casterBounds, const ShadowSettings& shadow,
Alec Mouribd17b3b2020-12-17 11:08:30 -0800463 const ubyte4& backgroundColor) {
464 const float shadowInset = shadow.length * -1.0f;
465 const Rect casterRect(casterBounds);
466 const Rect shadowRect =
467 Rect(casterRect).inset(shadowInset, shadowInset, shadowInset, shadowInset);
468
469 const Region backgroundRegion =
470 Region(fullscreenRect()).subtractSelf(casterRect).subtractSelf(shadowRect);
471
472 expectAlpha(shadowRect, 255);
473 // (0, 0, 0) fill on the bounds of the layer should be ignored.
474 expectBufferColor(casterRect, 255, 255, 255, 255, 254);
475
476 // verify background
477 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
478 backgroundColor.a);
479 }
480
Vishnu Naird9e4f462023-10-06 04:05:45 +0000481 static ShadowSettings getShadowSettings(const vec2& casterPos, float shadowLength,
482 bool casterIsTranslucent) {
483 ShadowSettings shadow;
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800484 shadow.ambientColor = {0.0f, 0.0f, 0.0f, 0.039f};
485 shadow.spotColor = {0.0f, 0.0f, 0.0f, 0.19f};
486 shadow.lightPos = vec3(casterPos.x, casterPos.y, 0);
487 shadow.lightRadius = 0.0f;
488 shadow.length = shadowLength;
489 shadow.casterIsTranslucent = casterIsTranslucent;
490 return shadow;
491 }
492
Alec Mouri1089aed2018-10-25 21:33:57 -0700493 static Rect fullscreenRect() { return Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT); }
494
495 static Rect offsetRect() {
496 return Rect(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_WIDTH,
497 DEFAULT_DISPLAY_HEIGHT);
498 }
499
500 static Rect offsetRectAtZero() {
501 return Rect(DEFAULT_DISPLAY_WIDTH - DEFAULT_DISPLAY_OFFSET,
502 DEFAULT_DISPLAY_HEIGHT - DEFAULT_DISPLAY_OFFSET);
503 }
504
Sally Qi59a9f502021-10-12 18:53:23 +0000505 void invokeDraw(const renderengine::DisplaySettings& settings,
506 const std::vector<renderengine::LayerSettings>& layers) {
Patrick Williams2e9748f2022-08-09 22:48:18 +0000507 ftl::Future<FenceResult> future =
Alec Mourif29700f2023-08-17 21:53:31 +0000508 mRE->drawLayers(settings, layers, mBuffer, base::unique_fd());
Patrick Williams2e9748f2022-08-09 22:48:18 +0000509 ASSERT_TRUE(future.valid());
Sally Qi59a9f502021-10-12 18:53:23 +0000510
Patrick Williams2e9748f2022-08-09 22:48:18 +0000511 auto result = future.get();
512 ASSERT_TRUE(result.ok());
Alec Mouri1089aed2018-10-25 21:33:57 -0700513
Patrick Williams2e9748f2022-08-09 22:48:18 +0000514 auto fence = result.value();
515 fence->waitForever(LOG_TAG);
Alec Mouri1089aed2018-10-25 21:33:57 -0700516 }
517
Alec Mourid43ccab2019-03-13 12:23:45 -0700518 void drawEmptyLayers() {
Alec Mouri6e57f682018-09-29 20:45:08 -0700519 renderengine::DisplaySettings settings;
Sally Qi59a9f502021-10-12 18:53:23 +0000520 std::vector<renderengine::LayerSettings> layers;
Alec Mouric0aae732021-01-12 13:32:18 -0800521 invokeDraw(settings, layers);
Alec Mouri6e57f682018-09-29 20:45:08 -0700522 }
523
Alec Mouri1089aed2018-10-25 21:33:57 -0700524 template <typename SourceVariant>
525 void fillBuffer(half r, half g, half b, half a);
526
527 template <typename SourceVariant>
528 void fillRedBuffer();
529
530 template <typename SourceVariant>
531 void fillGreenBuffer();
532
533 template <typename SourceVariant>
534 void fillBlueBuffer();
535
536 template <typename SourceVariant>
537 void fillRedTransparentBuffer();
538
539 template <typename SourceVariant>
540 void fillRedOffsetBuffer();
541
542 template <typename SourceVariant>
543 void fillBufferPhysicalOffset();
544
545 template <typename SourceVariant>
Alec Mouri5a6d8572020-03-23 23:56:15 -0700546 void fillBufferCheckers(uint32_t rotation);
Alec Mouri1089aed2018-10-25 21:33:57 -0700547
548 template <typename SourceVariant>
549 void fillBufferCheckersRotate0();
550
551 template <typename SourceVariant>
552 void fillBufferCheckersRotate90();
553
554 template <typename SourceVariant>
555 void fillBufferCheckersRotate180();
556
557 template <typename SourceVariant>
558 void fillBufferCheckersRotate270();
559
560 template <typename SourceVariant>
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800561 void fillBufferWithLayerTransform();
562
563 template <typename SourceVariant>
Alec Mouri1089aed2018-10-25 21:33:57 -0700564 void fillBufferLayerTransform();
565
566 template <typename SourceVariant>
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800567 void fillBufferWithColorTransform();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800568
569 template <typename SourceVariant>
Alec Mouri1089aed2018-10-25 21:33:57 -0700570 void fillBufferColorTransform();
571
Alec Mouri7c94edb2018-12-03 21:23:26 -0800572 template <typename SourceVariant>
Sally Qi2019fd22021-11-22 10:19:04 -0800573 void fillBufferWithColorTransformAndSourceDataspace(const ui::Dataspace sourceDataspace);
574
575 template <typename SourceVariant>
576 void fillBufferColorTransformAndSourceDataspace();
577
578 template <typename SourceVariant>
579 void fillBufferWithColorTransformAndOutputDataspace(const ui::Dataspace outputDataspace);
580
581 template <typename SourceVariant>
582 void fillBufferColorTransformAndOutputDataspace();
583
584 template <typename SourceVariant>
KaiChieh Chuangda2845c2020-12-14 16:49:38 +0800585 void fillBufferWithColorTransformZeroLayerAlpha();
586
587 template <typename SourceVariant>
588 void fillBufferColorTransformZeroLayerAlpha();
589
590 template <typename SourceVariant>
Alec Mouri7c94edb2018-12-03 21:23:26 -0800591 void fillRedBufferWithRoundedCorners();
592
593 template <typename SourceVariant>
594 void fillBufferWithRoundedCorners();
595
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000596 template <typename SourceVariant>
Lucas Dupin19c8f0e2019-11-25 17:55:44 -0800597 void fillBufferAndBlurBackground();
598
599 template <typename SourceVariant>
Alec Mourie8489fd2021-04-29 16:08:56 -0700600 void fillSmallLayerAndBlurBackground();
601
602 template <typename SourceVariant>
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000603 void overlayCorners();
604
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800605 void fillRedBufferTextureTransform();
606
607 void fillBufferTextureTransform();
608
609 void fillRedBufferWithPremultiplyAlpha();
610
611 void fillBufferWithPremultiplyAlpha();
612
613 void fillRedBufferWithoutPremultiplyAlpha();
614
615 void fillBufferWithoutPremultiplyAlpha();
616
Alec Mouriac335532018-11-12 15:01:33 -0800617 void fillGreenColorBufferThenClearRegion();
618
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800619 template <typename SourceVariant>
Vishnu Naird9e4f462023-10-06 04:05:45 +0000620 void drawShadow(const renderengine::LayerSettings& castingLayer, const ShadowSettings& shadow,
621 const ubyte4& casterColor, const ubyte4& backgroundColor);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800622
Vishnu Naird9e4f462023-10-06 04:05:45 +0000623 void drawShadowWithoutCaster(const FloatRect& castingBounds, const ShadowSettings& shadow,
Alec Mouribd17b3b2020-12-17 11:08:30 -0800624 const ubyte4& backgroundColor);
625
Alec Mouri5a493722022-01-26 16:43:02 -0800626 // Tonemaps grey values from sourceDataspace -> Display P3 and checks that GPU and CPU
627 // implementations are identical Also implicitly checks that the injected tonemap shader
628 // compiles
629 void tonemap(ui::Dataspace sourceDataspace, std::function<vec3(vec3)> eotf,
630 std::function<vec3(vec3, float)> scaleOotf);
631
Alec Mouric0aae732021-01-12 13:32:18 -0800632 void initializeRenderEngine();
633
634 std::unique_ptr<renderengine::RenderEngine> mRE;
Alec Mouria90a5702021-04-16 16:36:21 +0000635 std::shared_ptr<renderengine::ExternalTexture> mBuffer;
Alec Mouri6e57f682018-09-29 20:45:08 -0700636};
637
Alec Mouric0aae732021-01-12 13:32:18 -0800638void RenderEngineTest::initializeRenderEngine() {
639 const auto& renderEngineFactory = GetParam();
Alec Mouric16974e2022-09-13 17:35:48 +0000640 mRE = renderEngineFactory->createRenderEngine();
Alec Mouria90a5702021-04-16 16:36:21 +0000641 mBuffer = allocateDefaultBuffer();
Alec Mouric0aae732021-01-12 13:32:18 -0800642}
643
Alec Mouri1089aed2018-10-25 21:33:57 -0700644struct ColorSourceVariant {
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800645 static void fillColor(renderengine::LayerSettings& layer, half r, half g, half b,
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800646 RenderEngineTest* /*fixture*/) {
Alec Mouri1089aed2018-10-25 21:33:57 -0700647 layer.source.solidColor = half3(r, g, b);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800648 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700649 }
650};
651
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800652struct RelaxOpaqueBufferVariant {
653 static void setOpaqueBit(renderengine::LayerSettings& layer) {
654 layer.source.buffer.isOpaque = false;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800655 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800656 }
657
658 static uint8_t getAlphaChannel() { return 255; }
659};
660
661struct ForceOpaqueBufferVariant {
662 static void setOpaqueBit(renderengine::LayerSettings& layer) {
663 layer.source.buffer.isOpaque = true;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800664 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800665 }
666
667 static uint8_t getAlphaChannel() {
668 // The isOpaque bit will override the alpha channel, so this should be
669 // arbitrary.
Alec Mouric0aae732021-01-12 13:32:18 -0800670 return 50;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800671 }
672};
673
674template <typename OpaquenessVariant>
675struct BufferSourceVariant {
676 static void fillColor(renderengine::LayerSettings& layer, half r, half g, half b,
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800677 RenderEngineTest* fixture) {
Alec Mouria90a5702021-04-16 16:36:21 +0000678 const auto buf = fixture->allocateSourceBuffer(1, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800679
680 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +0000681 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
682 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800683
Alec Mouria90a5702021-04-16 16:36:21 +0000684 for (int32_t j = 0; j < buf->getBuffer()->getHeight(); j++) {
685 uint8_t* iter = pixels + (buf->getBuffer()->getStride() * j) * 4;
686 for (int32_t i = 0; i < buf->getBuffer()->getWidth(); i++) {
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800687 iter[0] = uint8_t(r * 255);
688 iter[1] = uint8_t(g * 255);
689 iter[2] = uint8_t(b * 255);
690 iter[3] = OpaquenessVariant::getAlphaChannel();
691 iter += 4;
692 }
693 }
694
Alec Mouria90a5702021-04-16 16:36:21 +0000695 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800696
697 layer.source.buffer.buffer = buf;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800698 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800699 OpaquenessVariant::setOpaqueBit(layer);
700 }
701};
702
Alec Mouri1089aed2018-10-25 21:33:57 -0700703template <typename SourceVariant>
704void RenderEngineTest::fillBuffer(half r, half g, half b, half a) {
705 renderengine::DisplaySettings settings;
706 settings.physicalDisplay = fullscreenRect();
707 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800708 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700709
Sally Qi59a9f502021-10-12 18:53:23 +0000710 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700711
712 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800713 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700714 layer.geometry.boundaries = fullscreenRect().toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800715 SourceVariant::fillColor(layer, r, g, b, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700716 layer.alpha = a;
717
Sally Qi59a9f502021-10-12 18:53:23 +0000718 layers.push_back(layer);
Alec Mouri1089aed2018-10-25 21:33:57 -0700719
Alec Mouric0aae732021-01-12 13:32:18 -0800720 invokeDraw(settings, layers);
Alec Mouri1089aed2018-10-25 21:33:57 -0700721}
722
723template <typename SourceVariant>
724void RenderEngineTest::fillRedBuffer() {
725 fillBuffer<SourceVariant>(1.0f, 0.0f, 0.0f, 1.0f);
726 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
727}
728
729template <typename SourceVariant>
730void RenderEngineTest::fillGreenBuffer() {
731 fillBuffer<SourceVariant>(0.0f, 1.0f, 0.0f, 1.0f);
732 expectBufferColor(fullscreenRect(), 0, 255, 0, 255);
733}
734
735template <typename SourceVariant>
736void RenderEngineTest::fillBlueBuffer() {
737 fillBuffer<SourceVariant>(0.0f, 0.0f, 1.0f, 1.0f);
738 expectBufferColor(fullscreenRect(), 0, 0, 255, 255);
739}
740
741template <typename SourceVariant>
742void RenderEngineTest::fillRedTransparentBuffer() {
743 fillBuffer<SourceVariant>(1.0f, 0.0f, 0.0f, .2f);
744 expectBufferColor(fullscreenRect(), 51, 0, 0, 51);
745}
746
747template <typename SourceVariant>
748void RenderEngineTest::fillRedOffsetBuffer() {
749 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 = offsetRect();
752 settings.clip = offsetRectAtZero();
753
Sally Qi59a9f502021-10-12 18:53:23 +0000754 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700755
756 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800757 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700758 layer.geometry.boundaries = offsetRectAtZero().toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800759 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700760 layer.alpha = 1.0f;
761
Sally Qi59a9f502021-10-12 18:53:23 +0000762 layers.push_back(layer);
Alec Mouric0aae732021-01-12 13:32:18 -0800763 invokeDraw(settings, layers);
Alec Mouri1089aed2018-10-25 21:33:57 -0700764}
765
766template <typename SourceVariant>
767void RenderEngineTest::fillBufferPhysicalOffset() {
768 fillRedOffsetBuffer<SourceVariant>();
769
770 expectBufferColor(Rect(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_WIDTH,
771 DEFAULT_DISPLAY_HEIGHT),
772 255, 0, 0, 255);
773 Rect offsetRegionLeft(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_HEIGHT);
774 Rect offsetRegionTop(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_OFFSET);
775
776 expectBufferColor(offsetRegionLeft, 0, 0, 0, 0);
777 expectBufferColor(offsetRegionTop, 0, 0, 0, 0);
778}
779
780template <typename SourceVariant>
Alec Mouri5a6d8572020-03-23 23:56:15 -0700781void RenderEngineTest::fillBufferCheckers(uint32_t orientationFlag) {
Alec Mouri1089aed2018-10-25 21:33:57 -0700782 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800783 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700784 settings.physicalDisplay = fullscreenRect();
785 // Here logical space is 2x2
786 settings.clip = Rect(2, 2);
Alec Mouri5a6d8572020-03-23 23:56:15 -0700787 settings.orientation = orientationFlag;
Alec Mouri1089aed2018-10-25 21:33:57 -0700788
Sally Qi59a9f502021-10-12 18:53:23 +0000789 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700790
791 renderengine::LayerSettings layerOne;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800792 layerOne.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700793 Rect rectOne(0, 0, 1, 1);
794 layerOne.geometry.boundaries = rectOne.toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800795 SourceVariant::fillColor(layerOne, 1.0f, 0.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700796 layerOne.alpha = 1.0f;
797
798 renderengine::LayerSettings layerTwo;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800799 layerTwo.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700800 Rect rectTwo(0, 1, 1, 2);
801 layerTwo.geometry.boundaries = rectTwo.toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800802 SourceVariant::fillColor(layerTwo, 0.0f, 1.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700803 layerTwo.alpha = 1.0f;
804
805 renderengine::LayerSettings layerThree;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800806 layerThree.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700807 Rect rectThree(1, 0, 2, 1);
808 layerThree.geometry.boundaries = rectThree.toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800809 SourceVariant::fillColor(layerThree, 0.0f, 0.0f, 1.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700810 layerThree.alpha = 1.0f;
811
Sally Qi59a9f502021-10-12 18:53:23 +0000812 layers.push_back(layerOne);
813 layers.push_back(layerTwo);
814 layers.push_back(layerThree);
Alec Mouri1089aed2018-10-25 21:33:57 -0700815
Alec Mouric0aae732021-01-12 13:32:18 -0800816 invokeDraw(settings, layers);
Alec Mouri1089aed2018-10-25 21:33:57 -0700817}
818
819template <typename SourceVariant>
820void RenderEngineTest::fillBufferCheckersRotate0() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700821 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_0);
Alec Mouri1089aed2018-10-25 21:33:57 -0700822 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0,
823 255);
824 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
825 DEFAULT_DISPLAY_HEIGHT / 2),
826 0, 0, 255, 255);
827 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
828 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
829 0, 0, 0, 0);
830 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
831 DEFAULT_DISPLAY_HEIGHT),
832 0, 255, 0, 255);
833}
834
835template <typename SourceVariant>
836void RenderEngineTest::fillBufferCheckersRotate90() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700837 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_90);
Alec Mouri1089aed2018-10-25 21:33:57 -0700838 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 255, 0,
839 255);
840 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
841 DEFAULT_DISPLAY_HEIGHT / 2),
842 255, 0, 0, 255);
843 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
844 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
845 0, 0, 255, 255);
846 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
847 DEFAULT_DISPLAY_HEIGHT),
848 0, 0, 0, 0);
849}
850
851template <typename SourceVariant>
852void RenderEngineTest::fillBufferCheckersRotate180() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700853 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_180);
Alec Mouri1089aed2018-10-25 21:33:57 -0700854 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 0,
855 0);
856 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
857 DEFAULT_DISPLAY_HEIGHT / 2),
858 0, 255, 0, 255);
859 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
860 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
861 255, 0, 0, 255);
862 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
863 DEFAULT_DISPLAY_HEIGHT),
864 0, 0, 255, 255);
865}
866
867template <typename SourceVariant>
868void RenderEngineTest::fillBufferCheckersRotate270() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700869 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_270);
Alec Mouri1089aed2018-10-25 21:33:57 -0700870 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 255,
871 255);
872 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
873 DEFAULT_DISPLAY_HEIGHT / 2),
874 0, 0, 0, 0);
875 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
876 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
877 0, 255, 0, 255);
878 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
879 DEFAULT_DISPLAY_HEIGHT),
880 255, 0, 0, 255);
881}
882
883template <typename SourceVariant>
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800884void RenderEngineTest::fillBufferWithLayerTransform() {
Alec Mouri1089aed2018-10-25 21:33:57 -0700885 renderengine::DisplaySettings settings;
886 settings.physicalDisplay = fullscreenRect();
887 // Here logical space is 2x2
888 settings.clip = Rect(2, 2);
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();
896 // Translate one pixel diagonally
897 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 -0800898 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700899 layer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
900 layer.alpha = 1.0f;
901
Sally Qi59a9f502021-10-12 18:53:23 +0000902 layers.push_back(layer);
Alec Mouri1089aed2018-10-25 21:33:57 -0700903
Alec Mouric0aae732021-01-12 13:32:18 -0800904 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800905}
Alec Mouri1089aed2018-10-25 21:33:57 -0700906
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800907template <typename SourceVariant>
908void RenderEngineTest::fillBufferLayerTransform() {
909 fillBufferWithLayerTransform<SourceVariant>();
Alec Mouri1089aed2018-10-25 21:33:57 -0700910 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 0, 0);
911 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
912 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
913 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
914 255, 0, 0, 255);
915}
916
917template <typename SourceVariant>
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800918void RenderEngineTest::fillBufferWithColorTransform() {
Alec Mouri1089aed2018-10-25 21:33:57 -0700919 renderengine::DisplaySettings settings;
920 settings.physicalDisplay = fullscreenRect();
921 settings.clip = Rect(1, 1);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800922 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700923
Sally Qi59a9f502021-10-12 18:53:23 +0000924 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700925
926 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800927 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700928 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800929 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700930 layer.alpha = 1.0f;
931
932 // construct a fake color matrix
933 // annihilate green and blue channels
KaiChieh Chuang436fc192020-09-07 13:48:42 +0800934 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
Alec Mouri1089aed2018-10-25 21:33:57 -0700935 // set red channel to red + green
936 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
937
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800938 layer.alpha = 1.0f;
939 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
940
Sally Qi59a9f502021-10-12 18:53:23 +0000941 layers.push_back(layer);
Alec Mouri1089aed2018-10-25 21:33:57 -0700942
Alec Mouric0aae732021-01-12 13:32:18 -0800943 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800944}
Alec Mouri1089aed2018-10-25 21:33:57 -0700945
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800946template <typename SourceVariant>
Sally Qi2019fd22021-11-22 10:19:04 -0800947void RenderEngineTest::fillBufferWithColorTransformAndSourceDataspace(
948 const ui::Dataspace sourceDataspace) {
949 renderengine::DisplaySettings settings;
950 settings.physicalDisplay = fullscreenRect();
951 settings.clip = Rect(1, 1);
952 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
953
954 std::vector<renderengine::LayerSettings> layers;
955
956 renderengine::LayerSettings layer;
Sally Qi2019fd22021-11-22 10:19:04 -0800957 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
958 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
Alec Mouric16974e2022-09-13 17:35:48 +0000959 layer.sourceDataspace = sourceDataspace;
Sally Qi2019fd22021-11-22 10:19:04 -0800960 layer.alpha = 1.0f;
961
962 // construct a fake color matrix
963 // annihilate green and blue channels
964 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
965 // set red channel to red + green
966 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
967
968 layer.alpha = 1.0f;
969 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
970
971 layers.push_back(layer);
972
973 invokeDraw(settings, layers);
974}
975
976template <typename SourceVariant>
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800977void RenderEngineTest::fillBufferColorTransform() {
978 fillBufferWithColorTransform<SourceVariant>();
KaiChieh Chuang436fc192020-09-07 13:48:42 +0800979 expectBufferColor(fullscreenRect(), 172, 0, 0, 255, 1);
980}
981
982template <typename SourceVariant>
Sally Qi2019fd22021-11-22 10:19:04 -0800983void RenderEngineTest::fillBufferColorTransformAndSourceDataspace() {
984 unordered_map<ui::Dataspace, ubyte4> dataspaceToColorMap;
Alec Mouric16974e2022-09-13 17:35:48 +0000985 dataspaceToColorMap[ui::Dataspace::V0_BT709] = {77, 0, 0, 255};
986 dataspaceToColorMap[ui::Dataspace::BT2020] = {101, 0, 0, 255};
987 dataspaceToColorMap[ui::Dataspace::ADOBE_RGB] = {75, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -0800988 ui::Dataspace customizedDataspace = static_cast<ui::Dataspace>(
989 ui::Dataspace::STANDARD_BT709 | ui::Dataspace::TRANSFER_GAMMA2_2 |
990 ui::Dataspace::RANGE_FULL);
Alec Mouric16974e2022-09-13 17:35:48 +0000991 dataspaceToColorMap[customizedDataspace] = {61, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -0800992 for (const auto& [sourceDataspace, color] : dataspaceToColorMap) {
993 fillBufferWithColorTransformAndSourceDataspace<SourceVariant>(sourceDataspace);
994 expectBufferColor(fullscreenRect(), color.r, color.g, color.b, color.a, 1);
995 }
996}
997
998template <typename SourceVariant>
999void RenderEngineTest::fillBufferWithColorTransformAndOutputDataspace(
1000 const ui::Dataspace outputDataspace) {
1001 renderengine::DisplaySettings settings;
1002 settings.physicalDisplay = fullscreenRect();
1003 settings.clip = Rect(1, 1);
1004 settings.outputDataspace = outputDataspace;
1005
1006 std::vector<renderengine::LayerSettings> layers;
1007
1008 renderengine::LayerSettings layer;
1009 layer.sourceDataspace = ui::Dataspace::V0_SCRGB_LINEAR;
1010 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1011 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
1012 layer.alpha = 1.0f;
1013
1014 // construct a fake color matrix
1015 // annihilate green and blue channels
1016 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
1017 // set red channel to red + green
1018 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
1019
1020 layer.alpha = 1.0f;
1021 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1022
1023 layers.push_back(layer);
1024
1025 invokeDraw(settings, layers);
1026}
1027
1028template <typename SourceVariant>
1029void RenderEngineTest::fillBufferColorTransformAndOutputDataspace() {
1030 unordered_map<ui::Dataspace, ubyte4> dataspaceToColorMap;
Alec Mouric16974e2022-09-13 17:35:48 +00001031 dataspaceToColorMap[ui::Dataspace::V0_BT709] = {198, 0, 0, 255};
1032 dataspaceToColorMap[ui::Dataspace::BT2020] = {187, 0, 0, 255};
1033 dataspaceToColorMap[ui::Dataspace::ADOBE_RGB] = {192, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -08001034 ui::Dataspace customizedDataspace = static_cast<ui::Dataspace>(
1035 ui::Dataspace::STANDARD_BT709 | ui::Dataspace::TRANSFER_GAMMA2_6 |
1036 ui::Dataspace::RANGE_FULL);
Alec Mouric16974e2022-09-13 17:35:48 +00001037 dataspaceToColorMap[customizedDataspace] = {205, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -08001038 for (const auto& [outputDataspace, color] : dataspaceToColorMap) {
1039 fillBufferWithColorTransformAndOutputDataspace<SourceVariant>(outputDataspace);
1040 expectBufferColor(fullscreenRect(), color.r, color.g, color.b, color.a, 1);
1041 }
1042}
1043
1044template <typename SourceVariant>
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001045void RenderEngineTest::fillBufferWithColorTransformZeroLayerAlpha() {
1046 renderengine::DisplaySettings settings;
1047 settings.physicalDisplay = fullscreenRect();
1048 settings.clip = Rect(1, 1);
1049
Sally Qi59a9f502021-10-12 18:53:23 +00001050 std::vector<renderengine::LayerSettings> layers;
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001051
1052 renderengine::LayerSettings layer;
1053 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1054 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
1055 layer.alpha = 0;
1056
1057 // construct a fake color matrix
1058 // simple inverse color
1059 settings.colorTransform = mat4(-1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 1, 1, 1, 1);
1060
1061 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1062
Sally Qi59a9f502021-10-12 18:53:23 +00001063 layers.push_back(layer);
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001064
Alec Mouric0aae732021-01-12 13:32:18 -08001065 invokeDraw(settings, layers);
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001066}
1067
1068template <typename SourceVariant>
1069void RenderEngineTest::fillBufferColorTransformZeroLayerAlpha() {
1070 fillBufferWithColorTransformZeroLayerAlpha<SourceVariant>();
1071 expectBufferColor(fullscreenRect(), 0, 0, 0, 0);
1072}
1073
1074template <typename SourceVariant>
Alec Mouri7c94edb2018-12-03 21:23:26 -08001075void RenderEngineTest::fillRedBufferWithRoundedCorners() {
1076 renderengine::DisplaySettings settings;
1077 settings.physicalDisplay = fullscreenRect();
1078 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001079 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri7c94edb2018-12-03 21:23:26 -08001080
Sally Qi59a9f502021-10-12 18:53:23 +00001081 std::vector<renderengine::LayerSettings> layers;
Alec Mouri7c94edb2018-12-03 21:23:26 -08001082
1083 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001084 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri7c94edb2018-12-03 21:23:26 -08001085 layer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07001086 layer.geometry.roundedCornersRadius = {5.0f, 5.0f};
Alec Mouri7c94edb2018-12-03 21:23:26 -08001087 layer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
1088 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
1089 layer.alpha = 1.0f;
1090
Sally Qi59a9f502021-10-12 18:53:23 +00001091 layers.push_back(layer);
Alec Mouri7c94edb2018-12-03 21:23:26 -08001092
Alec Mouric0aae732021-01-12 13:32:18 -08001093 invokeDraw(settings, layers);
Alec Mouri7c94edb2018-12-03 21:23:26 -08001094}
1095
1096template <typename SourceVariant>
1097void RenderEngineTest::fillBufferWithRoundedCorners() {
1098 fillRedBufferWithRoundedCorners<SourceVariant>();
1099 // Corners should be ignored...
1100 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 0);
1101 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, 0, DEFAULT_DISPLAY_WIDTH, 1), 0, 0, 0, 0);
1102 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT - 1, 1, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
1103 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1,
1104 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1105 0, 0, 0, 0);
1106 // ...And the non-rounded portion should be red.
1107 // Other pixels may be anti-aliased, so let's not check those.
1108 expectBufferColor(Rect(5, 5, DEFAULT_DISPLAY_WIDTH - 5, DEFAULT_DISPLAY_HEIGHT - 5), 255, 0, 0,
1109 255);
1110}
1111
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001112template <typename SourceVariant>
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001113void RenderEngineTest::fillBufferAndBlurBackground() {
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001114 auto blurRadius = 50;
1115 auto center = DEFAULT_DISPLAY_WIDTH / 2;
1116
1117 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001118 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001119 settings.physicalDisplay = fullscreenRect();
1120 settings.clip = fullscreenRect();
1121
Sally Qi59a9f502021-10-12 18:53:23 +00001122 std::vector<renderengine::LayerSettings> layers;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001123
1124 renderengine::LayerSettings backgroundLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001125 backgroundLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001126 backgroundLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1127 SourceVariant::fillColor(backgroundLayer, 0.0f, 1.0f, 0.0f, this);
1128 backgroundLayer.alpha = 1.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001129 layers.emplace_back(backgroundLayer);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001130
1131 renderengine::LayerSettings leftLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001132 leftLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001133 leftLayer.geometry.boundaries =
1134 Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT).toFloatRect();
1135 SourceVariant::fillColor(leftLayer, 1.0f, 0.0f, 0.0f, this);
1136 leftLayer.alpha = 1.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001137 layers.emplace_back(leftLayer);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001138
1139 renderengine::LayerSettings blurLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001140 blurLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001141 blurLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1142 blurLayer.backgroundBlurRadius = blurRadius;
Derek Sollenbergerecb21462021-01-29 16:53:49 -05001143 SourceVariant::fillColor(blurLayer, 0.0f, 0.0f, 1.0f, this);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001144 blurLayer.alpha = 0;
Sally Qi59a9f502021-10-12 18:53:23 +00001145 layers.emplace_back(blurLayer);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001146
Alec Mouric0aae732021-01-12 13:32:18 -08001147 invokeDraw(settings, layers);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001148
Derek Sollenbergerecb21462021-01-29 16:53:49 -05001149 // solid color
1150 expectBufferColor(Rect(0, 0, 1, 1), 255, 0, 0, 255, 0 /* tolerance */);
1151
Derek Sollenbergerb3998372021-02-16 15:16:56 -05001152 if (mRE->supportsBackgroundBlur()) {
1153 // blurred color (downsampling should result in the center color being close to 128)
1154 expectBufferColor(Rect(center - 1, center - 5, center + 1, center + 5), 128, 128, 0, 255,
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001155 50 /* tolerance */);
Derek Sollenbergerb3998372021-02-16 15:16:56 -05001156 }
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001157}
1158
1159template <typename SourceVariant>
Alec Mourie8489fd2021-04-29 16:08:56 -07001160void RenderEngineTest::fillSmallLayerAndBlurBackground() {
1161 auto blurRadius = 50;
1162 renderengine::DisplaySettings settings;
1163 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1164 settings.physicalDisplay = fullscreenRect();
1165 settings.clip = fullscreenRect();
1166
Sally Qi59a9f502021-10-12 18:53:23 +00001167 std::vector<renderengine::LayerSettings> layers;
Alec Mourie8489fd2021-04-29 16:08:56 -07001168
1169 renderengine::LayerSettings backgroundLayer;
1170 backgroundLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1171 backgroundLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1172 SourceVariant::fillColor(backgroundLayer, 1.0f, 0.0f, 0.0f, this);
1173 backgroundLayer.alpha = 1.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001174 layers.push_back(backgroundLayer);
Alec Mourie8489fd2021-04-29 16:08:56 -07001175
1176 renderengine::LayerSettings blurLayer;
1177 blurLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1178 blurLayer.geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f);
1179 blurLayer.backgroundBlurRadius = blurRadius;
1180 SourceVariant::fillColor(blurLayer, 0.0f, 0.0f, 1.0f, this);
1181 blurLayer.alpha = 0;
Sally Qi59a9f502021-10-12 18:53:23 +00001182 layers.push_back(blurLayer);
Alec Mourie8489fd2021-04-29 16:08:56 -07001183
1184 invokeDraw(settings, layers);
1185
1186 // Give a generous tolerance - the blur rectangle is very small and this test is
1187 // mainly concerned with ensuring that there's no device failure.
1188 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT), 255, 0, 0, 255,
1189 40 /* tolerance */);
1190}
1191
1192template <typename SourceVariant>
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001193void RenderEngineTest::overlayCorners() {
1194 renderengine::DisplaySettings settings;
1195 settings.physicalDisplay = fullscreenRect();
1196 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001197 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001198
Sally Qi59a9f502021-10-12 18:53:23 +00001199 std::vector<renderengine::LayerSettings> layersFirst;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001200
1201 renderengine::LayerSettings layerOne;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001202 layerOne.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001203 layerOne.geometry.boundaries =
1204 FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH / 3.0, DEFAULT_DISPLAY_HEIGHT / 3.0);
1205 SourceVariant::fillColor(layerOne, 1.0f, 0.0f, 0.0f, this);
1206 layerOne.alpha = 0.2;
1207
Sally Qi59a9f502021-10-12 18:53:23 +00001208 layersFirst.push_back(layerOne);
Alec Mouric0aae732021-01-12 13:32:18 -08001209 invokeDraw(settings, layersFirst);
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001210 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3), 51, 0, 0, 51);
1211 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3 + 1, DEFAULT_DISPLAY_HEIGHT / 3 + 1,
1212 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1213 0, 0, 0, 0);
1214
Sally Qi59a9f502021-10-12 18:53:23 +00001215 std::vector<renderengine::LayerSettings> layersSecond;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001216 renderengine::LayerSettings layerTwo;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001217 layerTwo.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001218 layerTwo.geometry.boundaries =
1219 FloatRect(DEFAULT_DISPLAY_WIDTH / 3.0, DEFAULT_DISPLAY_HEIGHT / 3.0,
1220 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT);
1221 SourceVariant::fillColor(layerTwo, 0.0f, 1.0f, 0.0f, this);
1222 layerTwo.alpha = 1.0f;
1223
Sally Qi59a9f502021-10-12 18:53:23 +00001224 layersSecond.push_back(layerTwo);
Alec Mouric0aae732021-01-12 13:32:18 -08001225 invokeDraw(settings, layersSecond);
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001226
1227 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3), 0, 0, 0, 0);
1228 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3 + 1, DEFAULT_DISPLAY_HEIGHT / 3 + 1,
1229 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1230 0, 255, 0, 255);
1231}
1232
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001233void RenderEngineTest::fillRedBufferTextureTransform() {
1234 renderengine::DisplaySettings settings;
1235 settings.physicalDisplay = fullscreenRect();
1236 settings.clip = Rect(1, 1);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001237 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001238
Sally Qi59a9f502021-10-12 18:53:23 +00001239 std::vector<renderengine::LayerSettings> layers;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001240
1241 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001242 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001243 // Here will allocate a checker board texture, but transform texture
1244 // coordinates so that only the upper left is applied.
Alec Mouria90a5702021-04-16 16:36:21 +00001245 const auto buf = allocateSourceBuffer(2, 2);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001246
1247 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00001248 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1249 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001250 // Red top left, Green top right, Blue bottom left, Black bottom right
1251 pixels[0] = 255;
1252 pixels[1] = 0;
1253 pixels[2] = 0;
1254 pixels[3] = 255;
1255 pixels[4] = 0;
1256 pixels[5] = 255;
1257 pixels[6] = 0;
1258 pixels[7] = 255;
1259 pixels[8] = 0;
1260 pixels[9] = 0;
1261 pixels[10] = 255;
1262 pixels[11] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00001263 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001264
1265 layer.source.buffer.buffer = buf;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001266 // Transform coordinates to only be inside the red quadrant.
Alec Mouri4049b532021-10-15 20:59:33 -07001267 layer.source.buffer.textureTransform = mat4::scale(vec4(0.2f, 0.2f, 1.f, 1.f));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001268 layer.alpha = 1.0f;
1269 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1270
Sally Qi59a9f502021-10-12 18:53:23 +00001271 layers.push_back(layer);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001272
Alec Mouric0aae732021-01-12 13:32:18 -08001273 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001274}
1275
1276void RenderEngineTest::fillBufferTextureTransform() {
1277 fillRedBufferTextureTransform();
1278 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
1279}
1280
1281void RenderEngineTest::fillRedBufferWithPremultiplyAlpha() {
1282 renderengine::DisplaySettings settings;
1283 settings.physicalDisplay = fullscreenRect();
1284 // Here logical space is 1x1
1285 settings.clip = Rect(1, 1);
1286
Sally Qi59a9f502021-10-12 18:53:23 +00001287 std::vector<renderengine::LayerSettings> layers;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001288
1289 renderengine::LayerSettings layer;
Alec Mouria90a5702021-04-16 16:36:21 +00001290 const auto buf = allocateSourceBuffer(1, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001291
1292 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00001293 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1294 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001295 pixels[0] = 255;
1296 pixels[1] = 0;
1297 pixels[2] = 0;
1298 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00001299 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001300
1301 layer.source.buffer.buffer = buf;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001302 layer.source.buffer.usePremultipliedAlpha = true;
1303 layer.alpha = 0.5f;
1304 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1305
Sally Qi59a9f502021-10-12 18:53:23 +00001306 layers.push_back(layer);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001307
Alec Mouric0aae732021-01-12 13:32:18 -08001308 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001309}
1310
1311void RenderEngineTest::fillBufferWithPremultiplyAlpha() {
1312 fillRedBufferWithPremultiplyAlpha();
Nolan Scobie01b93b12024-04-03 21:27:34 +00001313 // Different backends and GPUs may round 255 * 0.5 = 127.5 differently, but
1314 // either 127 or 128 are acceptable. Checking both 127 and 128 with a
1315 // tolerance of 1 allows either 127 or 128 to pass, while preventing 126 or
1316 // 129 from erroneously passing.
1317 expectBufferColor(fullscreenRect(), 127, 0, 0, 127, 1);
1318 expectBufferColor(fullscreenRect(), 128, 0, 0, 128, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001319}
1320
1321void RenderEngineTest::fillRedBufferWithoutPremultiplyAlpha() {
1322 renderengine::DisplaySettings settings;
1323 settings.physicalDisplay = fullscreenRect();
1324 // Here logical space is 1x1
1325 settings.clip = Rect(1, 1);
1326
Sally Qi59a9f502021-10-12 18:53:23 +00001327 std::vector<renderengine::LayerSettings> layers;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001328
1329 renderengine::LayerSettings layer;
Alec Mouria90a5702021-04-16 16:36:21 +00001330 const auto buf = allocateSourceBuffer(1, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001331
1332 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00001333 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1334 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001335 pixels[0] = 255;
1336 pixels[1] = 0;
1337 pixels[2] = 0;
1338 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00001339 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001340
1341 layer.source.buffer.buffer = buf;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001342 layer.source.buffer.usePremultipliedAlpha = false;
1343 layer.alpha = 0.5f;
1344 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1345
Sally Qi59a9f502021-10-12 18:53:23 +00001346 layers.push_back(layer);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001347
Alec Mouric0aae732021-01-12 13:32:18 -08001348 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001349}
1350
1351void RenderEngineTest::fillBufferWithoutPremultiplyAlpha() {
1352 fillRedBufferWithoutPremultiplyAlpha();
wukui16f3c0bb2020-08-05 20:35:29 +08001353 expectBufferColor(fullscreenRect(), 128, 0, 0, 128, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001354}
1355
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001356template <typename SourceVariant>
1357void RenderEngineTest::drawShadow(const renderengine::LayerSettings& castingLayer,
Vishnu Naird9e4f462023-10-06 04:05:45 +00001358 const ShadowSettings& shadow, const ubyte4& casterColor,
1359 const ubyte4& backgroundColor) {
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001360 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001361 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001362 settings.physicalDisplay = fullscreenRect();
1363 settings.clip = fullscreenRect();
1364
Sally Qi59a9f502021-10-12 18:53:23 +00001365 std::vector<renderengine::LayerSettings> layers;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001366
1367 // add background layer
1368 renderengine::LayerSettings bgLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001369 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001370 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1371 ColorSourceVariant::fillColor(bgLayer, backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1372 backgroundColor.b / 255.0f, this);
1373 bgLayer.alpha = backgroundColor.a / 255.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001374 layers.push_back(bgLayer);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001375
1376 // add shadow layer
1377 renderengine::LayerSettings shadowLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001378 shadowLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001379 shadowLayer.geometry.boundaries = castingLayer.geometry.boundaries;
1380 shadowLayer.alpha = castingLayer.alpha;
1381 shadowLayer.shadow = shadow;
Sally Qi59a9f502021-10-12 18:53:23 +00001382 layers.push_back(shadowLayer);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001383
1384 // add layer casting the shadow
1385 renderengine::LayerSettings layer = castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001386 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001387 SourceVariant::fillColor(layer, casterColor.r / 255.0f, casterColor.g / 255.0f,
1388 casterColor.b / 255.0f, this);
Sally Qi59a9f502021-10-12 18:53:23 +00001389 layers.push_back(layer);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001390
Alec Mouric0aae732021-01-12 13:32:18 -08001391 invokeDraw(settings, layers);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001392}
1393
Alec Mouribd17b3b2020-12-17 11:08:30 -08001394void RenderEngineTest::drawShadowWithoutCaster(const FloatRect& castingBounds,
Vishnu Naird9e4f462023-10-06 04:05:45 +00001395 const ShadowSettings& shadow,
Alec Mouribd17b3b2020-12-17 11:08:30 -08001396 const ubyte4& backgroundColor) {
1397 renderengine::DisplaySettings settings;
1398 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1399 settings.physicalDisplay = fullscreenRect();
1400 settings.clip = fullscreenRect();
1401
Sally Qi59a9f502021-10-12 18:53:23 +00001402 std::vector<renderengine::LayerSettings> layers;
Alec Mouribd17b3b2020-12-17 11:08:30 -08001403
1404 // add background layer
1405 renderengine::LayerSettings bgLayer;
1406 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1407 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1408 ColorSourceVariant::fillColor(bgLayer, backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1409 backgroundColor.b / 255.0f, this);
1410 bgLayer.alpha = backgroundColor.a / 255.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001411 layers.push_back(bgLayer);
Alec Mouribd17b3b2020-12-17 11:08:30 -08001412
1413 // add shadow layer
1414 renderengine::LayerSettings shadowLayer;
1415 shadowLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1416 shadowLayer.geometry.boundaries = castingBounds;
Derek Sollenbergerc31985e2021-05-18 16:38:17 -04001417 shadowLayer.skipContentDraw = true;
Alec Mouribd17b3b2020-12-17 11:08:30 -08001418 shadowLayer.alpha = 1.0f;
1419 ColorSourceVariant::fillColor(shadowLayer, 0, 0, 0, this);
1420 shadowLayer.shadow = shadow;
Sally Qi59a9f502021-10-12 18:53:23 +00001421 layers.push_back(shadowLayer);
Alec Mouribd17b3b2020-12-17 11:08:30 -08001422
Alec Mouric0aae732021-01-12 13:32:18 -08001423 invokeDraw(settings, layers);
Alec Mouribd17b3b2020-12-17 11:08:30 -08001424}
1425
Alec Mouri5a493722022-01-26 16:43:02 -08001426void RenderEngineTest::tonemap(ui::Dataspace sourceDataspace, std::function<vec3(vec3)> eotf,
1427 std::function<vec3(vec3, float)> scaleOotf) {
1428 constexpr int32_t kGreyLevels = 256;
1429
1430 const auto rect = Rect(0, 0, kGreyLevels, 1);
1431
1432 constexpr float kMaxLuminance = 750.f;
1433 constexpr float kCurrentLuminanceNits = 500.f;
1434 const renderengine::DisplaySettings display{
1435 .physicalDisplay = rect,
1436 .clip = rect,
1437 .maxLuminance = kMaxLuminance,
1438 .currentLuminanceNits = kCurrentLuminanceNits,
1439 .outputDataspace = ui::Dataspace::DISPLAY_P3,
1440 };
1441
1442 auto buf = 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 "input"),
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, buf->getBuffer()->initCheck());
1455 {
1456 uint8_t* pixels;
1457 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1458 reinterpret_cast<void**>(&pixels));
1459
1460 uint8_t color = 0;
1461 for (int32_t j = 0; j < buf->getBuffer()->getHeight(); j++) {
1462 uint8_t* dest = pixels + (buf->getBuffer()->getStride() * j * 4);
1463 for (int32_t i = 0; i < buf->getBuffer()->getWidth(); i++) {
1464 dest[0] = color;
1465 dest[1] = color;
1466 dest[2] = color;
1467 dest[3] = 255;
1468 color++;
1469 dest += 4;
1470 }
1471 }
1472 buf->getBuffer()->unlock();
1473 }
1474
1475 mBuffer = std::make_shared<
1476 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07001477 ExternalTexture>(sp<GraphicBuffer>::make(kGreyLevels, 1,
1478 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1479 GRALLOC_USAGE_SW_READ_OFTEN |
1480 GRALLOC_USAGE_SW_WRITE_OFTEN |
1481 GRALLOC_USAGE_HW_RENDER |
1482 GRALLOC_USAGE_HW_TEXTURE,
1483 "output"),
Alec Mouri5a493722022-01-26 16:43:02 -08001484 *mRE,
1485 renderengine::impl::ExternalTexture::Usage::READABLE |
1486 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
1487 ASSERT_EQ(0, mBuffer->getBuffer()->initCheck());
1488
1489 const renderengine::LayerSettings layer{.geometry.boundaries = rect.toFloatRect(),
1490 .source =
1491 renderengine::PixelSource{
1492 .buffer =
1493 renderengine::Buffer{
1494 .buffer =
1495 std::move(buf),
1496 .usePremultipliedAlpha =
1497 true,
1498 },
1499 },
1500 .alpha = 1.0f,
1501 .sourceDataspace = sourceDataspace};
1502
1503 std::vector<renderengine::LayerSettings> layers{layer};
1504 invokeDraw(display, layers);
1505
1506 ColorSpace displayP3 = ColorSpace::DisplayP3();
1507 ColorSpace bt2020 = ColorSpace::BT2020();
1508
1509 tonemap::Metadata metadata{.displayMaxLuminance = 750.0f};
1510
1511 auto generator = [=](Point location) {
1512 const double normColor = static_cast<double>(location.x) / (kGreyLevels - 1);
1513 const vec3 rgb = vec3(normColor, normColor, normColor);
1514
1515 const vec3 linearRGB = eotf(rgb);
1516
1517 const vec3 xyz = bt2020.getRGBtoXYZ() * linearRGB;
1518
1519 const vec3 scaledXYZ = scaleOotf(xyz, kCurrentLuminanceNits);
Alec Mouri196b0f22022-03-04 22:13:48 +00001520 const auto gains =
Alec Mouri5a493722022-01-26 16:43:02 -08001521 tonemap::getToneMapper()
1522 ->lookupTonemapGain(static_cast<aidl::android::hardware::graphics::common::
1523 Dataspace>(sourceDataspace),
1524 static_cast<aidl::android::hardware::graphics::common::
1525 Dataspace>(
1526 ui::Dataspace::DISPLAY_P3),
Alec Mouri196b0f22022-03-04 22:13:48 +00001527 {tonemap::
1528 Color{.linearRGB =
1529 scaleOotf(linearRGB,
1530 kCurrentLuminanceNits),
1531 .xyz = scaledXYZ}},
Alec Mouri5a493722022-01-26 16:43:02 -08001532 metadata);
Alec Mouri196b0f22022-03-04 22:13:48 +00001533 EXPECT_EQ(1, gains.size());
1534 const double gain = gains.front();
Alec Mouri5a493722022-01-26 16:43:02 -08001535 const vec3 normalizedXYZ = scaledXYZ * gain / metadata.displayMaxLuminance;
1536
1537 const vec3 targetRGB = OETF_sRGB(displayP3.getXYZtoRGB() * normalizedXYZ) * 255;
1538 return ubyte4(static_cast<uint8_t>(targetRGB.r), static_cast<uint8_t>(targetRGB.g),
1539 static_cast<uint8_t>(targetRGB.b), 255);
1540 };
1541
1542 expectBufferColor(Rect(kGreyLevels, 1), generator, 2);
1543}
1544
Nolan Scobie488101b2024-05-20 13:32:13 -04001545// TODO: b/341728634 - Clean up conditional compilation.
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001546INSTANTIATE_TEST_SUITE_P(PerRenderEngineType, RenderEngineTest,
Alec Mouric16974e2022-09-13 17:35:48 +00001547 testing::Values(std::make_shared<SkiaGLESRenderEngineFactory>(),
Nolan Scobie488101b2024-05-20 13:32:13 -04001548 std::make_shared<GaneshVkRenderEngineFactory>()
1549#if COMPILE_GRAPHITE_RENDERENGINE
1550 ,
1551 std::make_shared<GraphiteVkRenderEngineFactory>()
1552#endif
1553 ));
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001554
1555TEST_P(RenderEngineTest, drawLayers_noLayersToDraw) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001556 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001557 GTEST_SKIP();
1558 }
Alec Mouric0aae732021-01-12 13:32:18 -08001559 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001560 drawEmptyLayers();
1561}
1562
Sally Qi1fed86e2022-06-23 15:33:52 -07001563TEST_P(RenderEngineTest, drawLayers_fillRedBufferAndEmptyBuffer) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001564 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001565 GTEST_SKIP();
1566 }
Sally Qi1fed86e2022-06-23 15:33:52 -07001567 initializeRenderEngine();
1568 renderengine::DisplaySettings settings;
1569 settings.physicalDisplay = fullscreenRect();
1570 settings.clip = fullscreenRect();
1571 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1572
1573 // add a red layer
1574 renderengine::LayerSettings layerOne{
1575 .geometry.boundaries = fullscreenRect().toFloatRect(),
1576 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
1577 .alpha = 1.f,
1578 };
1579
1580 std::vector<renderengine::LayerSettings> layersFirst{layerOne};
1581 invokeDraw(settings, layersFirst);
1582 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
1583
1584 // re-draw with an empty layer above it, and we get a transparent black one
1585 std::vector<renderengine::LayerSettings> layersSecond;
1586 invokeDraw(settings, layersSecond);
1587 expectBufferColor(fullscreenRect(), 0, 0, 0, 0);
1588}
1589
Ana Krulec07b98df2021-01-07 14:38:40 -08001590TEST_P(RenderEngineTest, drawLayers_withoutBuffers_withColorTransform) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001591 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001592 GTEST_SKIP();
1593 }
Alec Mouria90a5702021-04-16 16:36:21 +00001594 initializeRenderEngine();
Ana Krulec07b98df2021-01-07 14:38:40 -08001595
1596 renderengine::DisplaySettings settings;
1597 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1598 settings.physicalDisplay = fullscreenRect();
1599 settings.clip = fullscreenRect();
1600
1601 // 255, 255, 255, 255 is full opaque white.
Alec Mouri4049b532021-10-15 20:59:33 -07001602 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
1603 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Ana Krulec07b98df2021-01-07 14:38:40 -08001604 // Create layer with given color.
1605 renderengine::LayerSettings bgLayer;
1606 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1607 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1608 bgLayer.source.solidColor = half3(backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1609 backgroundColor.b / 255.0f);
1610 bgLayer.alpha = backgroundColor.a / 255.0f;
1611 // Transform the red color.
1612 bgLayer.colorTransform = mat4(-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
1613
Sally Qi59a9f502021-10-12 18:53:23 +00001614 std::vector<renderengine::LayerSettings> layers;
1615 layers.push_back(bgLayer);
Ana Krulec07b98df2021-01-07 14:38:40 -08001616
Alec Mouric0aae732021-01-12 13:32:18 -08001617 invokeDraw(settings, layers);
Ana Krulec07b98df2021-01-07 14:38:40 -08001618
1619 // Expect to see full opaque pixel (with inverted red from the transform).
Alec Mouric0aae732021-01-12 13:32:18 -08001620 expectBufferColor(Rect(0, 0, 10, 10), 0.f, backgroundColor.g, backgroundColor.b,
Ana Krulec07b98df2021-01-07 14:38:40 -08001621 backgroundColor.a);
1622}
1623
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001624TEST_P(RenderEngineTest, drawLayers_nullOutputBuffer) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001625 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001626 GTEST_SKIP();
1627 }
Alec Mouric0aae732021-01-12 13:32:18 -08001628 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001629
Alec Mourid43ccab2019-03-13 12:23:45 -07001630 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001631 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Sally Qi59a9f502021-10-12 18:53:23 +00001632 std::vector<renderengine::LayerSettings> layers;
Alec Mourid43ccab2019-03-13 12:23:45 -07001633 renderengine::LayerSettings layer;
1634 layer.geometry.boundaries = fullscreenRect().toFloatRect();
1635 BufferSourceVariant<ForceOpaqueBufferVariant>::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
Sally Qi59a9f502021-10-12 18:53:23 +00001636 layers.push_back(layer);
Alec Mourif29700f2023-08-17 21:53:31 +00001637 ftl::Future<FenceResult> future = mRE->drawLayers(settings, layers, nullptr, base::unique_fd());
Alec Mourid43ccab2019-03-13 12:23:45 -07001638
Patrick Williams2e9748f2022-08-09 22:48:18 +00001639 ASSERT_TRUE(future.valid());
1640 auto result = future.get();
1641 ASSERT_FALSE(result.ok());
1642 ASSERT_EQ(BAD_VALUE, result.error());
Alec Mourid43ccab2019-03-13 12:23:45 -07001643}
1644
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001645TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001646 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001647 GTEST_SKIP();
1648 }
Alec Mouric0aae732021-01-12 13:32:18 -08001649 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001650 fillRedBuffer<ColorSourceVariant>();
1651}
1652
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001653TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001654 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001655 GTEST_SKIP();
1656 }
Alec Mouric0aae732021-01-12 13:32:18 -08001657 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001658 fillGreenBuffer<ColorSourceVariant>();
1659}
1660
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001661TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001662 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001663 GTEST_SKIP();
1664 }
Alec Mouric0aae732021-01-12 13:32:18 -08001665 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001666 fillBlueBuffer<ColorSourceVariant>();
1667}
1668
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001669TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001670 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001671 GTEST_SKIP();
1672 }
Alec Mouric0aae732021-01-12 13:32:18 -08001673 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001674 fillRedTransparentBuffer<ColorSourceVariant>();
1675}
1676
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001677TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001678 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001679 GTEST_SKIP();
1680 }
Alec Mouric0aae732021-01-12 13:32:18 -08001681 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001682 fillBufferPhysicalOffset<ColorSourceVariant>();
1683}
1684
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001685TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001686 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001687 GTEST_SKIP();
1688 }
Alec Mouric0aae732021-01-12 13:32:18 -08001689 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001690 fillBufferCheckersRotate0<ColorSourceVariant>();
1691}
1692
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001693TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001694 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001695 GTEST_SKIP();
1696 }
Alec Mouric0aae732021-01-12 13:32:18 -08001697 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001698 fillBufferCheckersRotate90<ColorSourceVariant>();
1699}
1700
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001701TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001702 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001703 GTEST_SKIP();
1704 }
Alec Mouric0aae732021-01-12 13:32:18 -08001705 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001706 fillBufferCheckersRotate180<ColorSourceVariant>();
1707}
1708
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001709TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001710 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001711 GTEST_SKIP();
1712 }
Alec Mouric0aae732021-01-12 13:32:18 -08001713 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001714 fillBufferCheckersRotate270<ColorSourceVariant>();
1715}
1716
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001717TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001718 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001719 GTEST_SKIP();
1720 }
Alec Mouric0aae732021-01-12 13:32:18 -08001721 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001722 fillBufferLayerTransform<ColorSourceVariant>();
1723}
1724
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001725TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001726 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001727 GTEST_SKIP();
1728 }
Alec Mouric0aae732021-01-12 13:32:18 -08001729 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08001730 fillBufferColorTransform<ColorSourceVariant>();
1731}
1732
Sally Qi2019fd22021-11-22 10:19:04 -08001733TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_sourceDataspace) {
1734 const auto& renderEngineFactory = GetParam();
1735 // skip for non color management
Leon Scroggins III696bf932024-01-24 15:21:05 -05001736 if (!renderEngineFactory->apiSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001737 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001738 }
1739
1740 initializeRenderEngine();
1741 fillBufferColorTransformAndSourceDataspace<ColorSourceVariant>();
1742}
1743
1744TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_outputDataspace) {
1745 const auto& renderEngineFactory = GetParam();
1746 // skip for non color management
Leon Scroggins III696bf932024-01-24 15:21:05 -05001747 if (!renderEngineFactory->apiSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001748 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001749 }
1750
1751 initializeRenderEngine();
1752 fillBufferColorTransformAndOutputDataspace<ColorSourceVariant>();
1753}
1754
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001755TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001756 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001757 GTEST_SKIP();
1758 }
Alec Mouric0aae732021-01-12 13:32:18 -08001759 initializeRenderEngine();
Alec Mouri7c94edb2018-12-03 21:23:26 -08001760 fillBufferWithRoundedCorners<ColorSourceVariant>();
1761}
1762
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001763TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001764 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001765 GTEST_SKIP();
1766 }
Alec Mouric0aae732021-01-12 13:32:18 -08001767 initializeRenderEngine();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001768 fillBufferColorTransformZeroLayerAlpha<ColorSourceVariant>();
1769}
1770
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001771TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001772 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001773 GTEST_SKIP();
1774 }
Alec Mouric0aae732021-01-12 13:32:18 -08001775 initializeRenderEngine();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001776 fillBufferAndBlurBackground<ColorSourceVariant>();
1777}
1778
Alec Mourie8489fd2021-04-29 16:08:56 -07001779TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001780 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001781 GTEST_SKIP();
1782 }
Alec Mourie8489fd2021-04-29 16:08:56 -07001783 initializeRenderEngine();
1784 fillSmallLayerAndBlurBackground<ColorSourceVariant>();
1785}
1786
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001787TEST_P(RenderEngineTest, drawLayers_overlayCorners_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001788 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001789 GTEST_SKIP();
1790 }
Alec Mouric0aae732021-01-12 13:32:18 -08001791 initializeRenderEngine();
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001792 overlayCorners<ColorSourceVariant>();
1793}
1794
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001795TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001796 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001797 GTEST_SKIP();
1798 }
Alec Mouric0aae732021-01-12 13:32:18 -08001799 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001800 fillRedBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1801}
1802
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001803TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001804 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001805 GTEST_SKIP();
1806 }
Alec Mouric0aae732021-01-12 13:32:18 -08001807 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001808 fillGreenBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1809}
1810
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001811TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001812 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001813 GTEST_SKIP();
1814 }
Alec Mouric0aae732021-01-12 13:32:18 -08001815 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001816 fillBlueBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1817}
1818
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001819TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001820 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001821 GTEST_SKIP();
1822 }
Alec Mouric0aae732021-01-12 13:32:18 -08001823 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001824 fillRedTransparentBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1825}
1826
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001827TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001828 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001829 GTEST_SKIP();
1830 }
Alec Mouric0aae732021-01-12 13:32:18 -08001831 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001832 fillBufferPhysicalOffset<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1833}
1834
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001835TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001836 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001837 GTEST_SKIP();
1838 }
Alec Mouric0aae732021-01-12 13:32:18 -08001839 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001840 fillBufferCheckersRotate0<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1841}
1842
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001843TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001844 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001845 GTEST_SKIP();
1846 }
Alec Mouric0aae732021-01-12 13:32:18 -08001847 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001848 fillBufferCheckersRotate90<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1849}
1850
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001851TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001852 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001853 GTEST_SKIP();
1854 }
Alec Mouric0aae732021-01-12 13:32:18 -08001855 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001856 fillBufferCheckersRotate180<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1857}
1858
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001859TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001860 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001861 GTEST_SKIP();
1862 }
Alec Mouric0aae732021-01-12 13:32:18 -08001863 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001864 fillBufferCheckersRotate270<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1865}
1866
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001867TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001868 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001869 GTEST_SKIP();
1870 }
Alec Mouric0aae732021-01-12 13:32:18 -08001871 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001872 fillBufferLayerTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1873}
1874
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001875TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001876 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001877 GTEST_SKIP();
1878 }
Alec Mouric0aae732021-01-12 13:32:18 -08001879 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08001880 fillBufferColorTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1881}
1882
Sally Qi2019fd22021-11-22 10:19:04 -08001883TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndSourceDataspace_opaqueBufferSource) {
1884 const auto& renderEngineFactory = GetParam();
1885 // skip for non color management
Leon Scroggins III696bf932024-01-24 15:21:05 -05001886 if (!renderEngineFactory->apiSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001887 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001888 }
1889
1890 initializeRenderEngine();
1891 fillBufferColorTransformAndSourceDataspace<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1892}
1893
1894TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndOutputDataspace_opaqueBufferSource) {
1895 const auto& renderEngineFactory = GetParam();
1896 // skip for non color management
Leon Scroggins III696bf932024-01-24 15:21:05 -05001897 if (!renderEngineFactory->apiSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001898 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001899 }
1900
1901 initializeRenderEngine();
1902 fillBufferColorTransformAndOutputDataspace<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1903}
1904
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001905TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001906 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001907 GTEST_SKIP();
1908 }
Alec Mouric0aae732021-01-12 13:32:18 -08001909 initializeRenderEngine();
Alec Mouri7c94edb2018-12-03 21:23:26 -08001910 fillBufferWithRoundedCorners<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1911}
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001912
Alec Mouric0aae732021-01-12 13:32:18 -08001913TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001914 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001915 GTEST_SKIP();
1916 }
Alec Mouric0aae732021-01-12 13:32:18 -08001917 initializeRenderEngine();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001918 fillBufferColorTransformZeroLayerAlpha<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1919}
Alec Mouri7c94edb2018-12-03 21:23:26 -08001920
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001921TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001922 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001923 GTEST_SKIP();
1924 }
Alec Mouric0aae732021-01-12 13:32:18 -08001925 initializeRenderEngine();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001926 fillBufferAndBlurBackground<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1927}
1928
Alec Mourie8489fd2021-04-29 16:08:56 -07001929TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001930 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001931 GTEST_SKIP();
1932 }
Alec Mourie8489fd2021-04-29 16:08:56 -07001933 initializeRenderEngine();
1934 fillSmallLayerAndBlurBackground<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1935}
1936
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001937TEST_P(RenderEngineTest, drawLayers_overlayCorners_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001938 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001939 GTEST_SKIP();
1940 }
Alec Mouric0aae732021-01-12 13:32:18 -08001941 initializeRenderEngine();
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001942 overlayCorners<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1943}
1944
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001945TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001946 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001947 GTEST_SKIP();
1948 }
Alec Mouric0aae732021-01-12 13:32:18 -08001949 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001950 fillRedBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1951}
1952
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001953TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001954 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001955 GTEST_SKIP();
1956 }
Alec Mouric0aae732021-01-12 13:32:18 -08001957 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001958 fillGreenBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1959}
1960
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001961TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001962 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001963 GTEST_SKIP();
1964 }
Alec Mouric0aae732021-01-12 13:32:18 -08001965 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001966 fillBlueBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1967}
1968
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001969TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001970 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001971 GTEST_SKIP();
1972 }
Alec Mouric0aae732021-01-12 13:32:18 -08001973 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001974 fillRedTransparentBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1975}
1976
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001977TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001978 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001979 GTEST_SKIP();
1980 }
Alec Mouric0aae732021-01-12 13:32:18 -08001981 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001982 fillBufferPhysicalOffset<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1983}
1984
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001985TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001986 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001987 GTEST_SKIP();
1988 }
Alec Mouric0aae732021-01-12 13:32:18 -08001989 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001990 fillBufferCheckersRotate0<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1991}
1992
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001993TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001994 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001995 GTEST_SKIP();
1996 }
Alec Mouric0aae732021-01-12 13:32:18 -08001997 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001998 fillBufferCheckersRotate90<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1999}
2000
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002001TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002002 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002003 GTEST_SKIP();
2004 }
Alec Mouric0aae732021-01-12 13:32:18 -08002005 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002006 fillBufferCheckersRotate180<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2007}
2008
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002009TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002010 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002011 GTEST_SKIP();
2012 }
Alec Mouric0aae732021-01-12 13:32:18 -08002013 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002014 fillBufferCheckersRotate270<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2015}
2016
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002017TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002018 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002019 GTEST_SKIP();
2020 }
Alec Mouric0aae732021-01-12 13:32:18 -08002021 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002022 fillBufferLayerTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2023}
2024
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002025TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002026 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002027 GTEST_SKIP();
2028 }
Alec Mouric0aae732021-01-12 13:32:18 -08002029 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08002030 fillBufferColorTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2031}
2032
Sally Qi2019fd22021-11-22 10:19:04 -08002033TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndSourceDataspace_bufferSource) {
2034 const auto& renderEngineFactory = GetParam();
2035 // skip for non color management
Leon Scroggins III696bf932024-01-24 15:21:05 -05002036 if (!renderEngineFactory->apiSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00002037 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08002038 }
2039
2040 initializeRenderEngine();
2041 fillBufferColorTransformAndSourceDataspace<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2042}
2043
2044TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndOutputDataspace_bufferSource) {
2045 const auto& renderEngineFactory = GetParam();
2046 // skip for non color management
Leon Scroggins III696bf932024-01-24 15:21:05 -05002047 if (!renderEngineFactory->apiSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00002048 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08002049 }
2050
2051 initializeRenderEngine();
2052 fillBufferColorTransformAndOutputDataspace<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2053}
2054
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002055TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002056 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002057 GTEST_SKIP();
2058 }
Alec Mouric0aae732021-01-12 13:32:18 -08002059 initializeRenderEngine();
Alec Mouri7c94edb2018-12-03 21:23:26 -08002060 fillBufferWithRoundedCorners<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2061}
2062
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08002063TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002064 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002065 GTEST_SKIP();
2066 }
Alec Mouric0aae732021-01-12 13:32:18 -08002067 initializeRenderEngine();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08002068 fillBufferColorTransformZeroLayerAlpha<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2069}
2070
Nathaniel Nifong53494f32021-04-30 14:05:39 -04002071TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002072 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002073 GTEST_SKIP();
2074 }
Alec Mouric0aae732021-01-12 13:32:18 -08002075 initializeRenderEngine();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08002076 fillBufferAndBlurBackground<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2077}
2078
Alec Mourie8489fd2021-04-29 16:08:56 -07002079TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002080 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002081 GTEST_SKIP();
2082 }
Alec Mourie8489fd2021-04-29 16:08:56 -07002083 initializeRenderEngine();
2084 fillSmallLayerAndBlurBackground<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2085}
2086
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002087TEST_P(RenderEngineTest, drawLayers_overlayCorners_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002088 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002089 GTEST_SKIP();
2090 }
Alec Mouric0aae732021-01-12 13:32:18 -08002091 initializeRenderEngine();
Alec Mourie7d1d4a2019-02-05 01:13:46 +00002092 overlayCorners<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2093}
2094
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002095TEST_P(RenderEngineTest, drawLayers_fillBufferTextureTransform) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002096 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002097 GTEST_SKIP();
2098 }
Alec Mouric0aae732021-01-12 13:32:18 -08002099 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002100 fillBufferTextureTransform();
2101}
2102
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002103TEST_P(RenderEngineTest, drawLayers_fillBuffer_premultipliesAlpha) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002104 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002105 GTEST_SKIP();
2106 }
Alec Mouric0aae732021-01-12 13:32:18 -08002107 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002108 fillBufferWithPremultiplyAlpha();
2109}
2110
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002111TEST_P(RenderEngineTest, drawLayers_fillBuffer_withoutPremultiplyingAlpha) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002112 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002113 GTEST_SKIP();
2114 }
Alec Mouric0aae732021-01-12 13:32:18 -08002115 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002116 fillBufferWithoutPremultiplyAlpha();
2117}
2118
Alec Mouribd17b3b2020-12-17 11:08:30 -08002119TEST_P(RenderEngineTest, drawLayers_fillShadow_castsWithoutCasterLayer) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002120 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002121 GTEST_SKIP();
2122 }
Alec Mouric0aae732021-01-12 13:32:18 -08002123 initializeRenderEngine();
Alec Mouribd17b3b2020-12-17 11:08:30 -08002124
Alec Mouri4049b532021-10-15 20:59:33 -07002125 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2126 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Alec Mouribd17b3b2020-12-17 11:08:30 -08002127 const float shadowLength = 5.0f;
2128 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2129 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
Vishnu Naird9e4f462023-10-06 04:05:45 +00002130 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2131 shadowLength, false /* casterIsTranslucent */);
Alec Mouribd17b3b2020-12-17 11:08:30 -08002132
2133 drawShadowWithoutCaster(casterBounds.toFloatRect(), settings, backgroundColor);
2134 expectShadowColorWithoutCaster(casterBounds.toFloatRect(), settings, backgroundColor);
2135}
2136
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002137TEST_P(RenderEngineTest, drawLayers_fillShadow_casterLayerMinSize) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002138 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002139 GTEST_SKIP();
2140 }
Alec Mouric0aae732021-01-12 13:32:18 -08002141 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002142
Alec Mouri4049b532021-10-15 20:59:33 -07002143 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2144 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2145 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2146 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002147 const float shadowLength = 5.0f;
2148 Rect casterBounds(1, 1);
2149 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2150 renderengine::LayerSettings castingLayer;
2151 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2152 castingLayer.alpha = 1.0f;
Vishnu Naird9e4f462023-10-06 04:05:45 +00002153 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2154 shadowLength, false /* casterIsTranslucent */);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002155
2156 drawShadow<ColorSourceVariant>(castingLayer, settings, casterColor, backgroundColor);
2157 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2158}
2159
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002160TEST_P(RenderEngineTest, drawLayers_fillShadow_casterColorLayer) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002161 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002162 GTEST_SKIP();
2163 }
Alec Mouric0aae732021-01-12 13:32:18 -08002164 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002165
Alec Mouri4049b532021-10-15 20:59:33 -07002166 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2167 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2168 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2169 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002170 const float shadowLength = 5.0f;
2171 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2172 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2173 renderengine::LayerSettings castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002174 castingLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002175 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2176 castingLayer.alpha = 1.0f;
Vishnu Naird9e4f462023-10-06 04:05:45 +00002177 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2178 shadowLength, false /* casterIsTranslucent */);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002179
2180 drawShadow<ColorSourceVariant>(castingLayer, settings, casterColor, backgroundColor);
2181 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2182}
2183
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002184TEST_P(RenderEngineTest, drawLayers_fillShadow_casterOpaqueBufferLayer) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002185 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002186 GTEST_SKIP();
2187 }
Alec Mouric0aae732021-01-12 13:32:18 -08002188 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002189
Alec Mouri4049b532021-10-15 20:59:33 -07002190 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2191 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2192 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2193 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002194 const float shadowLength = 5.0f;
2195 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2196 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2197 renderengine::LayerSettings castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002198 castingLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002199 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2200 castingLayer.alpha = 1.0f;
Vishnu Naird9e4f462023-10-06 04:05:45 +00002201 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2202 shadowLength, false /* casterIsTranslucent */);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002203
2204 drawShadow<BufferSourceVariant<ForceOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2205 backgroundColor);
2206 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2207}
2208
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002209TEST_P(RenderEngineTest, drawLayers_fillShadow_casterWithRoundedCorner) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002210 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002211 GTEST_SKIP();
2212 }
Alec Mouric0aae732021-01-12 13:32:18 -08002213 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002214
Alec Mouri4049b532021-10-15 20:59:33 -07002215 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2216 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2217 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2218 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002219 const float shadowLength = 5.0f;
2220 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2221 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2222 renderengine::LayerSettings castingLayer;
2223 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002224 castingLayer.geometry.roundedCornersRadius = {3.0f, 3.0f};
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002225 castingLayer.geometry.roundedCornersCrop = casterBounds.toFloatRect();
2226 castingLayer.alpha = 1.0f;
Vishnu Naird9e4f462023-10-06 04:05:45 +00002227 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2228 shadowLength, false /* casterIsTranslucent */);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002229
2230 drawShadow<BufferSourceVariant<ForceOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2231 backgroundColor);
2232 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2233}
2234
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002235TEST_P(RenderEngineTest, drawLayers_fillShadow_translucentCasterWithAlpha) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002236 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002237 GTEST_SKIP();
2238 }
Alec Mouric0aae732021-01-12 13:32:18 -08002239 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002240
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002241 const ubyte4 casterColor(255, 0, 0, 255);
2242 const ubyte4 backgroundColor(255, 255, 255, 255);
2243 const float shadowLength = 5.0f;
2244 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2245 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2246 renderengine::LayerSettings castingLayer;
2247 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2248 castingLayer.alpha = 0.5f;
Vishnu Naird9e4f462023-10-06 04:05:45 +00002249 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2250 shadowLength, true /* casterIsTranslucent */);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002251
2252 drawShadow<BufferSourceVariant<RelaxOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2253 backgroundColor);
2254
2255 // verify only the background since the shadow will draw behind the caster
2256 const float shadowInset = settings.length * -1.0f;
2257 const Rect casterWithShadow =
2258 Rect(casterBounds).inset(shadowInset, shadowInset, shadowInset, shadowInset);
2259 const Region backgroundRegion = Region(fullscreenRect()).subtractSelf(casterWithShadow);
2260 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
2261 backgroundColor.a);
2262}
2263
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002264TEST_P(RenderEngineTest, cleanupPostRender_cleansUpOnce) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002265 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002266 GTEST_SKIP();
2267 }
Alec Mouric0aae732021-01-12 13:32:18 -08002268 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002269
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002270 renderengine::DisplaySettings settings;
2271 settings.physicalDisplay = fullscreenRect();
2272 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002273 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002274
Sally Qi59a9f502021-10-12 18:53:23 +00002275 std::vector<renderengine::LayerSettings> layers;
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002276 renderengine::LayerSettings layer;
2277 layer.geometry.boundaries = fullscreenRect().toFloatRect();
2278 BufferSourceVariant<ForceOpaqueBufferVariant>::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
2279 layer.alpha = 1.0;
Sally Qi59a9f502021-10-12 18:53:23 +00002280 layers.push_back(layer);
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002281
Patrick Williams2e9748f2022-08-09 22:48:18 +00002282 ftl::Future<FenceResult> futureOne =
Alec Mourif29700f2023-08-17 21:53:31 +00002283 mRE->drawLayers(settings, layers, mBuffer, base::unique_fd());
Patrick Williams2e9748f2022-08-09 22:48:18 +00002284 ASSERT_TRUE(futureOne.valid());
2285 auto resultOne = futureOne.get();
2286 ASSERT_TRUE(resultOne.ok());
2287 auto fenceOne = resultOne.value();
Sally Qi4cabdd02021-08-05 16:45:57 -07002288
Patrick Williams2e9748f2022-08-09 22:48:18 +00002289 ftl::Future<FenceResult> futureTwo =
Alec Mourif29700f2023-08-17 21:53:31 +00002290 mRE->drawLayers(settings, layers, mBuffer, base::unique_fd(fenceOne->dup()));
Patrick Williams2e9748f2022-08-09 22:48:18 +00002291 ASSERT_TRUE(futureTwo.valid());
2292 auto resultTwo = futureTwo.get();
2293 ASSERT_TRUE(resultTwo.ok());
2294 auto fenceTwo = resultTwo.value();
2295 fenceTwo->waitForever(LOG_TAG);
Derek Sollenbergerec411212021-08-25 10:54:47 -04002296
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002297 // Only cleanup the first time.
Ian Elliott1f0911e2022-09-09 16:31:47 -06002298 if (mRE->canSkipPostRenderCleanup()) {
2299 // Skia's Vk backend may keep the texture alive beyond drawLayersInternal, so
2300 // it never gets added to the cleanup list. In those cases, we can skip.
Leon Scroggins III696bf932024-01-24 15:21:05 -05002301 EXPECT_TRUE(GetParam()->graphicsApi() == renderengine::RenderEngine::GraphicsApi::VK);
Ian Elliott1f0911e2022-09-09 16:31:47 -06002302 } else {
2303 mRE->cleanupPostRender();
2304 EXPECT_TRUE(mRE->canSkipPostRenderCleanup());
2305 }
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002306}
2307
Ana Krulecf9a15d92020-12-11 08:35:00 -08002308TEST_P(RenderEngineTest, testRoundedCornersCrop) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002309 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002310 GTEST_SKIP();
2311 }
Alec Mouric0aae732021-01-12 13:32:18 -08002312 initializeRenderEngine();
Ana Krulecf9a15d92020-12-11 08:35:00 -08002313
2314 renderengine::DisplaySettings settings;
2315 settings.physicalDisplay = fullscreenRect();
2316 settings.clip = fullscreenRect();
2317 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2318
Sally Qi59a9f502021-10-12 18:53:23 +00002319 std::vector<renderengine::LayerSettings> layers;
Ana Krulecf9a15d92020-12-11 08:35:00 -08002320
2321 renderengine::LayerSettings redLayer;
2322 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2323 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002324 redLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
2325
Ana Krulecf9a15d92020-12-11 08:35:00 -08002326 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2327 // Red background.
2328 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2329 redLayer.alpha = 1.0f;
2330
Sally Qi59a9f502021-10-12 18:53:23 +00002331 layers.push_back(redLayer);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002332
2333 // Green layer with 1/3 size.
2334 renderengine::LayerSettings greenLayer;
2335 greenLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2336 greenLayer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002337 greenLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
Ana Krulecf9a15d92020-12-11 08:35:00 -08002338 // Bottom right corner is not going to be rounded.
2339 greenLayer.geometry.roundedCornersCrop =
2340 Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3, DEFAULT_DISPLAY_HEIGHT,
2341 DEFAULT_DISPLAY_HEIGHT)
2342 .toFloatRect();
2343 greenLayer.source.solidColor = half3(0.0f, 1.0f, 0.0f);
2344 greenLayer.alpha = 1.0f;
2345
Sally Qi59a9f502021-10-12 18:53:23 +00002346 layers.push_back(greenLayer);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002347
Alec Mouric0aae732021-01-12 13:32:18 -08002348 invokeDraw(settings, layers);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002349
2350 // Corners should be ignored...
2351 // Screen size: width is 128, height is 256.
2352 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 0);
2353 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, 0, DEFAULT_DISPLAY_WIDTH, 1), 0, 0, 0, 0);
2354 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT - 1, 1, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
2355 // Bottom right corner is kept out of the clipping, and it's green.
2356 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1,
2357 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
2358 0, 255, 0, 255);
2359}
2360
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002361TEST_P(RenderEngineTest, testRoundedCornersParentCrop) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002362 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002363 GTEST_SKIP();
2364 }
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002365 initializeRenderEngine();
2366
2367 renderengine::DisplaySettings settings;
2368 settings.physicalDisplay = fullscreenRect();
2369 settings.clip = fullscreenRect();
2370 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2371
Sally Qi59a9f502021-10-12 18:53:23 +00002372 std::vector<renderengine::LayerSettings> layers;
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002373
2374 renderengine::LayerSettings redLayer;
2375 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2376 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002377 redLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002378 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2379 // Red background.
2380 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2381 redLayer.alpha = 1.0f;
2382
Sally Qi59a9f502021-10-12 18:53:23 +00002383 layers.push_back(redLayer);
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002384
2385 // Green layer with 1/2 size with parent crop rect.
2386 renderengine::LayerSettings greenLayer = redLayer;
2387 greenLayer.geometry.boundaries =
2388 FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT / 2);
2389 greenLayer.source.solidColor = half3(0.0f, 1.0f, 0.0f);
2390
Sally Qi59a9f502021-10-12 18:53:23 +00002391 layers.push_back(greenLayer);
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002392
2393 invokeDraw(settings, layers);
2394
2395 // Due to roundedCornersRadius, the corners are untouched.
2396 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2397 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2398 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2399 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2400
2401 // top middle should be green and the bottom middle red
2402 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, 0), 0, 255, 0, 255);
2403 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0, 255);
2404
2405 // the bottom edge of the green layer should not be rounded
2406 expectBufferColor(Point(0, (DEFAULT_DISPLAY_HEIGHT / 2) - 1), 0, 255, 0, 255);
2407}
2408
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002409TEST_P(RenderEngineTest, testRoundedCornersParentCropSmallBounds) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002410 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002411 GTEST_SKIP();
2412 }
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002413 initializeRenderEngine();
2414
2415 renderengine::DisplaySettings settings;
2416 settings.physicalDisplay = fullscreenRect();
2417 settings.clip = fullscreenRect();
2418 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2419
Sally Qi59a9f502021-10-12 18:53:23 +00002420 std::vector<renderengine::LayerSettings> layers;
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002421
2422 renderengine::LayerSettings redLayer;
2423 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2424 redLayer.geometry.boundaries = FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, 32);
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002425 redLayer.geometry.roundedCornersRadius = {64.0f, 64.0f};
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002426 redLayer.geometry.roundedCornersCrop = FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, 128);
2427 // Red background.
2428 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2429 redLayer.alpha = 1.0f;
2430
Sally Qi59a9f502021-10-12 18:53:23 +00002431 layers.push_back(redLayer);
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002432 invokeDraw(settings, layers);
2433
2434 // Due to roundedCornersRadius, the top corners are untouched.
2435 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2436 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2437
2438 // ensure that the entire height of the red layer was clipped by the rounded corners crop.
2439 expectBufferColor(Point(0, 31), 0, 0, 0, 0);
2440 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 31), 0, 0, 0, 0);
2441
2442 // the bottom middle should be red
2443 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, 31), 255, 0, 0, 255);
2444}
2445
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002446TEST_P(RenderEngineTest, testRoundedCornersXY) {
Leon Scroggins III9ba31e32024-01-25 11:40:26 -05002447 if (!GetParam()->apiSupported()) {
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002448 GTEST_SKIP();
2449 }
2450
2451 initializeRenderEngine();
2452
2453 renderengine::DisplaySettings settings;
2454 settings.physicalDisplay = fullscreenRect();
2455 settings.clip = fullscreenRect();
2456 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2457
2458 std::vector<renderengine::LayerSettings> layers;
2459
2460 renderengine::LayerSettings redLayer;
2461 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2462 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
2463 redLayer.geometry.roundedCornersRadius = {5.0f, 20.0f};
2464 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2465 // Red background.
2466 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2467 redLayer.alpha = 1.0f;
2468
2469 layers.push_back(redLayer);
2470
2471 invokeDraw(settings, layers);
2472
2473 // Due to roundedCornersRadius, the corners are untouched.
2474 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2475 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2476 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2477 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2478
2479 // Y-axis draws a larger radius, check that its untouched as well
2480 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 5), 0, 0, 0, 0);
2481 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 5), 0, 0, 0, 0);
2482 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 5), 0, 0, 0, 0);
2483 expectBufferColor(Point(0, 5), 0, 0, 0, 0);
2484
2485 // middle should be red
2486 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0, 255);
2487}
2488
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002489TEST_P(RenderEngineTest, testClear) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002490 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002491 GTEST_SKIP();
2492 }
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002493 initializeRenderEngine();
2494
2495 const auto rect = fullscreenRect();
2496 const renderengine::DisplaySettings display{
2497 .physicalDisplay = rect,
2498 .clip = rect,
2499 };
2500
2501 const renderengine::LayerSettings redLayer{
2502 .geometry.boundaries = rect.toFloatRect(),
2503 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
2504 .alpha = 1.0f,
2505 };
2506
2507 // This mimics prepareClearClientComposition. This layer should overwrite
2508 // the redLayer, so that the buffer is transparent, rather than red.
2509 const renderengine::LayerSettings clearLayer{
2510 .geometry.boundaries = rect.toFloatRect(),
2511 .source.solidColor = half3(0.0f, 0.0f, 0.0f),
2512 .alpha = 0.0f,
2513 .disableBlending = true,
2514 };
2515
Sally Qi59a9f502021-10-12 18:53:23 +00002516 std::vector<renderengine::LayerSettings> layers{redLayer, clearLayer};
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002517 invokeDraw(display, layers);
2518 expectBufferColor(rect, 0, 0, 0, 0);
2519}
2520
2521TEST_P(RenderEngineTest, testDisableBlendingBuffer) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002522 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002523 GTEST_SKIP();
2524 }
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002525 initializeRenderEngine();
2526
2527 const auto rect = Rect(0, 0, 1, 1);
2528 const renderengine::DisplaySettings display{
2529 .physicalDisplay = rect,
2530 .clip = rect,
2531 };
2532
2533 const renderengine::LayerSettings redLayer{
2534 .geometry.boundaries = rect.toFloatRect(),
2535 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
2536 .alpha = 1.0f,
2537 };
2538
2539 // The next layer will overwrite redLayer with a GraphicBuffer that is green
2540 // applied with a translucent alpha.
Alec Mouria90a5702021-04-16 16:36:21 +00002541 const auto buf = allocateSourceBuffer(1, 1);
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002542 {
2543 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00002544 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2545 reinterpret_cast<void**>(&pixels));
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002546 pixels[0] = 0;
2547 pixels[1] = 255;
2548 pixels[2] = 0;
2549 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00002550 buf->getBuffer()->unlock();
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002551 }
2552
2553 const renderengine::LayerSettings greenLayer{
2554 .geometry.boundaries = rect.toFloatRect(),
2555 .source =
2556 renderengine::PixelSource{
2557 .buffer =
2558 renderengine::Buffer{
2559 .buffer = buf,
2560 .usePremultipliedAlpha = true,
2561 },
2562 },
2563 .alpha = 0.5f,
2564 .disableBlending = true,
2565 };
2566
Sally Qi59a9f502021-10-12 18:53:23 +00002567 std::vector<renderengine::LayerSettings> layers{redLayer, greenLayer};
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002568 invokeDraw(display, layers);
2569 expectBufferColor(rect, 0, 128, 0, 128);
2570}
2571
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002572TEST_P(RenderEngineTest, testDimming) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002573 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002574 GTEST_SKIP();
2575 }
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002576 initializeRenderEngine();
2577
Alec Mouri85065692022-03-18 00:58:26 +00002578 const ui::Dataspace dataspace = ui::Dataspace::V0_SRGB_LINEAR;
2579
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002580 const auto displayRect = Rect(3, 1);
2581 const renderengine::DisplaySettings display{
2582 .physicalDisplay = displayRect,
2583 .clip = displayRect,
Alec Mouri85065692022-03-18 00:58:26 +00002584 .outputDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002585 .targetLuminanceNits = 1000.f,
2586 };
2587
2588 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2589 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2590 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2591
2592 const renderengine::LayerSettings greenLayer{
2593 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2594 .source =
2595 renderengine::PixelSource{
2596 .buffer =
2597 renderengine::Buffer{
2598 .buffer = greenBuffer,
2599 .usePremultipliedAlpha = true,
2600 },
2601 },
2602 .alpha = 1.0f,
Alec Mouri85065692022-03-18 00:58:26 +00002603 .sourceDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002604 .whitePointNits = 200.f,
2605 };
2606
2607 const renderengine::LayerSettings blueLayer{
2608 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2609 .source =
2610 renderengine::PixelSource{
2611 .buffer =
2612 renderengine::Buffer{
2613 .buffer = blueBuffer,
2614 .usePremultipliedAlpha = true,
2615 },
2616 },
2617 .alpha = 1.0f,
Alec Mouri85065692022-03-18 00:58:26 +00002618 .sourceDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002619 .whitePointNits = 1000.f / 51.f,
2620 };
2621
2622 const renderengine::LayerSettings redLayer{
2623 .geometry.boundaries = FloatRect(2.f, 0.f, 3.f, 1.f),
2624 .source =
2625 renderengine::PixelSource{
2626 .buffer =
2627 renderengine::Buffer{
2628 .buffer = redBuffer,
2629 .usePremultipliedAlpha = true,
2630 },
2631 },
2632 .alpha = 1.0f,
Alec Mouri85065692022-03-18 00:58:26 +00002633 .sourceDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002634 // When the white point is not set for a layer, just ignore it and treat it as the same
2635 // as the max layer
2636 .whitePointNits = -1.f,
2637 };
2638
2639 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer, redLayer};
2640 invokeDraw(display, layers);
2641
2642 expectBufferColor(Rect(1, 1), 0, 51, 0, 255, 1);
2643 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 5, 255, 1);
2644 expectBufferColor(Rect(2, 0, 3, 1), 51, 0, 0, 255, 1);
2645}
2646
Alec Mouri85065692022-03-18 00:58:26 +00002647TEST_P(RenderEngineTest, testDimming_inGammaSpace) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002648 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002649 GTEST_SKIP();
2650 }
Alec Mouri85065692022-03-18 00:58:26 +00002651 initializeRenderEngine();
2652
2653 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2654 ui::Dataspace::TRANSFER_GAMMA2_2 |
2655 ui::Dataspace::RANGE_FULL);
2656
2657 const auto displayRect = Rect(3, 1);
2658 const renderengine::DisplaySettings display{
2659 .physicalDisplay = displayRect,
2660 .clip = displayRect,
2661 .outputDataspace = dataspace,
2662 .targetLuminanceNits = 1000.f,
2663 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2664 };
2665
2666 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2667 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2668 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2669
2670 const renderengine::LayerSettings greenLayer{
2671 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2672 .source =
2673 renderengine::PixelSource{
2674 .buffer =
2675 renderengine::Buffer{
2676 .buffer = greenBuffer,
2677 .usePremultipliedAlpha = true,
2678 },
2679 },
2680 .alpha = 1.0f,
2681 .sourceDataspace = dataspace,
2682 .whitePointNits = 200.f,
2683 };
2684
2685 const renderengine::LayerSettings blueLayer{
2686 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2687 .source =
2688 renderengine::PixelSource{
2689 .buffer =
2690 renderengine::Buffer{
2691 .buffer = blueBuffer,
2692 .usePremultipliedAlpha = true,
2693 },
2694 },
2695 .alpha = 1.0f,
2696 .sourceDataspace = dataspace,
2697 .whitePointNits = 1000.f / 51.f,
2698 };
2699
2700 const renderengine::LayerSettings redLayer{
2701 .geometry.boundaries = FloatRect(2.f, 0.f, 3.f, 1.f),
2702 .source =
2703 renderengine::PixelSource{
2704 .buffer =
2705 renderengine::Buffer{
2706 .buffer = redBuffer,
2707 .usePremultipliedAlpha = true,
2708 },
2709 },
2710 .alpha = 1.0f,
2711 .sourceDataspace = dataspace,
2712 // When the white point is not set for a layer, just ignore it and treat it as the same
2713 // as the max layer
2714 .whitePointNits = -1.f,
2715 };
2716
2717 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer, redLayer};
2718 invokeDraw(display, layers);
2719
2720 expectBufferColor(Rect(1, 1), 0, 122, 0, 255, 1);
2721 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 42, 255, 1);
2722 expectBufferColor(Rect(2, 0, 3, 1), 122, 0, 0, 255, 1);
2723}
2724
Alec Mouri9bcd1d12022-04-21 22:16:56 +00002725TEST_P(RenderEngineTest, testDimming_inGammaSpace_withDisplayColorTransform) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002726 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002727 GTEST_SKIP();
2728 }
Alec Mouri9bcd1d12022-04-21 22:16:56 +00002729 initializeRenderEngine();
2730
2731 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2732 ui::Dataspace::TRANSFER_GAMMA2_2 |
2733 ui::Dataspace::RANGE_FULL);
2734
2735 const auto displayRect = Rect(3, 1);
2736 const renderengine::DisplaySettings display{
2737 .physicalDisplay = displayRect,
2738 .clip = displayRect,
2739 .outputDataspace = dataspace,
2740 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
2741 .targetLuminanceNits = 1000.f,
2742 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2743 };
2744
2745 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2746 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2747 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2748
2749 const renderengine::LayerSettings greenLayer{
2750 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2751 .source =
2752 renderengine::PixelSource{
2753 .buffer =
2754 renderengine::Buffer{
2755 .buffer = greenBuffer,
2756 .usePremultipliedAlpha = true,
2757 },
2758 },
2759 .alpha = 1.0f,
2760 .sourceDataspace = dataspace,
2761 .whitePointNits = 200.f,
2762 };
2763
2764 const renderengine::LayerSettings redLayer{
2765 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2766 .source =
2767 renderengine::PixelSource{
2768 .buffer =
2769 renderengine::Buffer{
2770 .buffer = redBuffer,
2771 .usePremultipliedAlpha = true,
2772 },
2773 },
2774 .alpha = 1.0f,
2775 .sourceDataspace = dataspace,
2776 // When the white point is not set for a layer, just ignore it and treat it as the same
2777 // as the max layer
2778 .whitePointNits = -1.f,
2779 };
2780
2781 std::vector<renderengine::LayerSettings> layers{greenLayer, redLayer};
2782 invokeDraw(display, layers);
2783
2784 expectBufferColor(Rect(1, 1), 0, 0, 0, 255, 1);
2785 expectBufferColor(Rect(1, 0, 2, 1), 0, 122, 0, 255, 1);
2786}
2787
2788TEST_P(RenderEngineTest, testDimming_inGammaSpace_withDisplayColorTransform_deviceHandles) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002789 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002790 GTEST_SKIP();
2791 }
Alec Mouri9bcd1d12022-04-21 22:16:56 +00002792 initializeRenderEngine();
2793
2794 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2795 ui::Dataspace::TRANSFER_GAMMA2_2 |
2796 ui::Dataspace::RANGE_FULL);
2797
2798 const auto displayRect = Rect(3, 1);
2799 const renderengine::DisplaySettings display{
2800 .physicalDisplay = displayRect,
2801 .clip = displayRect,
2802 .outputDataspace = dataspace,
2803 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
2804 .deviceHandlesColorTransform = true,
2805 .targetLuminanceNits = 1000.f,
2806 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2807 };
2808
2809 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2810 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2811 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2812
2813 const renderengine::LayerSettings greenLayer{
2814 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2815 .source =
2816 renderengine::PixelSource{
2817 .buffer =
2818 renderengine::Buffer{
2819 .buffer = greenBuffer,
2820 .usePremultipliedAlpha = true,
2821 },
2822 },
2823 .alpha = 1.0f,
2824 .sourceDataspace = dataspace,
2825 .whitePointNits = 200.f,
2826 };
2827
2828 const renderengine::LayerSettings redLayer{
2829 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2830 .source =
2831 renderengine::PixelSource{
2832 .buffer =
2833 renderengine::Buffer{
2834 .buffer = redBuffer,
2835 .usePremultipliedAlpha = true,
2836 },
2837 },
2838 .alpha = 1.0f,
2839 .sourceDataspace = dataspace,
2840 // When the white point is not set for a layer, just ignore it and treat it as the same
2841 // as the max layer
2842 .whitePointNits = -1.f,
2843 };
2844
2845 std::vector<renderengine::LayerSettings> layers{greenLayer, redLayer};
2846 invokeDraw(display, layers);
2847
2848 expectBufferColor(Rect(1, 1), 0, 122, 0, 255, 1);
2849 expectBufferColor(Rect(1, 0, 2, 1), 122, 0, 0, 255, 1);
2850}
2851
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002852TEST_P(RenderEngineTest, testDimming_withoutTargetLuminance) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002853 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002854 GTEST_SKIP();
2855 }
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002856 initializeRenderEngine();
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002857
2858 const auto displayRect = Rect(2, 1);
2859 const renderengine::DisplaySettings display{
2860 .physicalDisplay = displayRect,
2861 .clip = displayRect,
2862 .outputDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2863 .targetLuminanceNits = -1.f,
2864 };
2865
2866 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2867 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2868
2869 const renderengine::LayerSettings greenLayer{
2870 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2871 .source =
2872 renderengine::PixelSource{
2873 .buffer =
2874 renderengine::Buffer{
2875 .buffer = greenBuffer,
2876 .usePremultipliedAlpha = true,
2877 },
2878 },
2879 .alpha = 1.0f,
2880 .sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2881 .whitePointNits = 200.f,
2882 };
2883
2884 const renderengine::LayerSettings blueLayer{
2885 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2886 .source =
2887 renderengine::PixelSource{
2888 .buffer =
2889 renderengine::Buffer{
2890 .buffer = blueBuffer,
2891 .usePremultipliedAlpha = true,
2892 },
2893 },
2894 .alpha = 1.0f,
2895 .sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2896 .whitePointNits = 1000.f,
2897 };
2898
2899 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer};
2900 invokeDraw(display, layers);
2901
2902 expectBufferColor(Rect(1, 1), 0, 51, 0, 255, 1);
2903 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 255, 255);
2904}
2905
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002906TEST_P(RenderEngineTest, test_isOpaque) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002907 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002908 GTEST_SKIP();
2909 }
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002910 initializeRenderEngine();
2911
2912 const auto rect = Rect(0, 0, 1, 1);
2913 const renderengine::DisplaySettings display{
2914 .physicalDisplay = rect,
2915 .clip = rect,
2916 .outputDataspace = ui::Dataspace::DISPLAY_P3,
2917 };
2918
2919 // Create an unpremul buffer that is green with no alpha. Using isOpaque
2920 // should make the green show.
2921 const auto buf = allocateSourceBuffer(1, 1);
2922 {
2923 uint8_t* pixels;
2924 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2925 reinterpret_cast<void**>(&pixels));
2926 pixels[0] = 0;
2927 pixels[1] = 255;
2928 pixels[2] = 0;
2929 pixels[3] = 0;
2930 buf->getBuffer()->unlock();
2931 }
2932
2933 const renderengine::LayerSettings greenLayer{
2934 .geometry.boundaries = rect.toFloatRect(),
2935 .source =
2936 renderengine::PixelSource{
2937 .buffer =
2938 renderengine::Buffer{
2939 .buffer = buf,
2940 // Although the pixels are not
2941 // premultiplied in practice, this
2942 // matches the input we see.
2943 .usePremultipliedAlpha = true,
2944 .isOpaque = true,
2945 },
2946 },
2947 .alpha = 1.0f,
2948 };
2949
Sally Qi59a9f502021-10-12 18:53:23 +00002950 std::vector<renderengine::LayerSettings> layers{greenLayer};
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002951 invokeDraw(display, layers);
2952
Alec Mouri47bcb072023-08-15 02:02:49 +00002953 expectBufferColor(rect, 117, 251, 76, 255);
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002954}
Alec Mouri4049b532021-10-15 20:59:33 -07002955
Alec Mouri4049b532021-10-15 20:59:33 -07002956TEST_P(RenderEngineTest, test_tonemapPQMatches) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002957 if (!GetParam()->apiSupported()) {
Alec Mouri5a493722022-01-26 16:43:02 -08002958 GTEST_SKIP();
Alec Mouri4049b532021-10-15 20:59:33 -07002959 }
2960
Alec Mouri4049b532021-10-15 20:59:33 -07002961 initializeRenderEngine();
2962
Alec Mouri5a493722022-01-26 16:43:02 -08002963 tonemap(
2964 static_cast<ui::Dataspace>(HAL_DATASPACE_STANDARD_BT2020 |
2965 HAL_DATASPACE_TRANSFER_ST2084 | HAL_DATASPACE_RANGE_FULL),
2966 [](vec3 color) { return EOTF_PQ(color); },
2967 [](vec3 color, float) {
2968 static constexpr float kMaxPQLuminance = 10000.f;
2969 return color * kMaxPQLuminance;
2970 });
2971}
Alec Mouri4049b532021-10-15 20:59:33 -07002972
Alec Mouri5a493722022-01-26 16:43:02 -08002973TEST_P(RenderEngineTest, test_tonemapHLGMatches) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002974 if (!GetParam()->apiSupported()) {
Alec Mouri5a493722022-01-26 16:43:02 -08002975 GTEST_SKIP();
Alec Mouri4049b532021-10-15 20:59:33 -07002976 }
2977
Alec Mouri5a493722022-01-26 16:43:02 -08002978 initializeRenderEngine();
Alec Mouri4049b532021-10-15 20:59:33 -07002979
Alec Mouri5a493722022-01-26 16:43:02 -08002980 tonemap(
2981 static_cast<ui::Dataspace>(HAL_DATASPACE_STANDARD_BT2020 | HAL_DATASPACE_TRANSFER_HLG |
2982 HAL_DATASPACE_RANGE_FULL),
2983 [](vec3 color) { return EOTF_HLG(color); },
2984 [](vec3 color, float currentLuminaceNits) {
2985 static constexpr float kMaxHLGLuminance = 1000.f;
Alec Mouri7a577452022-03-04 23:41:38 +00002986 return color * kMaxHLGLuminance;
Alec Mouri5a493722022-01-26 16:43:02 -08002987 });
Alec Mouri4049b532021-10-15 20:59:33 -07002988}
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -05002989
2990TEST_P(RenderEngineTest, r8_behaves_as_mask) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002991 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002992 GTEST_SKIP();
2993 }
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -05002994 initializeRenderEngine();
2995
2996 const auto r8Buffer = allocateR8Buffer(2, 1);
2997 if (!r8Buffer) {
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05002998 GTEST_SKIP() << "Test is only necessary on devices that support r8";
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -05002999 return;
3000 }
3001 {
3002 uint8_t* pixels;
3003 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
3004 reinterpret_cast<void**>(&pixels));
3005 // This will be drawn on top of a green buffer. We'll verify that 255
3006 // results in keeping the original green and 0 results in black.
3007 pixels[0] = 0;
3008 pixels[1] = 255;
3009 r8Buffer->getBuffer()->unlock();
3010 }
3011
3012 const auto rect = Rect(0, 0, 2, 1);
3013 const renderengine::DisplaySettings display{
3014 .physicalDisplay = rect,
3015 .clip = rect,
3016 .outputDataspace = ui::Dataspace::SRGB,
3017 };
3018
3019 const auto greenBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(0, 255, 0, 255));
3020 const renderengine::LayerSettings greenLayer{
3021 .geometry.boundaries = rect.toFloatRect(),
3022 .source =
3023 renderengine::PixelSource{
3024 .buffer =
3025 renderengine::Buffer{
3026 .buffer = greenBuffer,
3027 },
3028 },
3029 .alpha = 1.0f,
3030 };
3031 const renderengine::LayerSettings r8Layer{
3032 .geometry.boundaries = rect.toFloatRect(),
3033 .source =
3034 renderengine::PixelSource{
3035 .buffer =
3036 renderengine::Buffer{
3037 .buffer = r8Buffer,
3038 },
3039 },
3040 .alpha = 1.0f,
3041 };
3042
3043 std::vector<renderengine::LayerSettings> layers{greenLayer, r8Layer};
3044 invokeDraw(display, layers);
3045
3046 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 255);
3047 expectBufferColor(Rect(1, 0, 2, 1), 0, 255, 0, 255);
3048}
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003049
3050TEST_P(RenderEngineTest, r8_respects_color_transform) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05003051 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003052 GTEST_SKIP();
3053 }
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003054 initializeRenderEngine();
3055
3056 const auto r8Buffer = allocateR8Buffer(2, 1);
3057 if (!r8Buffer) {
3058 GTEST_SKIP() << "Test is only necessary on devices that support r8";
3059 return;
3060 }
3061 {
3062 uint8_t* pixels;
3063 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
3064 reinterpret_cast<void**>(&pixels));
3065 pixels[0] = 0;
3066 pixels[1] = 255;
3067 r8Buffer->getBuffer()->unlock();
3068 }
3069
3070 const auto rect = Rect(0, 0, 2, 1);
3071 const renderengine::DisplaySettings display{
3072 .physicalDisplay = rect,
3073 .clip = rect,
3074 .outputDataspace = ui::Dataspace::SRGB,
3075 // Verify that the R8 layer respects the color transform when
3076 // deviceHandlesColorTransform is false. This transform converts
3077 // pure red to pure green. That will occur when the R8 buffer is
3078 // 255. When the R8 buffer is 0, it will still change to black, as
3079 // with r8_behaves_as_mask.
Alec Mouri9bcd1d12022-04-21 22:16:56 +00003080 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003081 .deviceHandlesColorTransform = false,
3082 };
3083
3084 const auto redBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(255, 0, 0, 255));
3085 const renderengine::LayerSettings redLayer{
3086 .geometry.boundaries = rect.toFloatRect(),
3087 .source =
3088 renderengine::PixelSource{
3089 .buffer =
3090 renderengine::Buffer{
3091 .buffer = redBuffer,
3092 },
3093 },
3094 .alpha = 1.0f,
3095 };
3096 const renderengine::LayerSettings r8Layer{
3097 .geometry.boundaries = rect.toFloatRect(),
3098 .source =
3099 renderengine::PixelSource{
3100 .buffer =
3101 renderengine::Buffer{
3102 .buffer = r8Buffer,
3103 },
3104 },
3105 .alpha = 1.0f,
3106 };
3107
3108 std::vector<renderengine::LayerSettings> layers{redLayer, r8Layer};
3109 invokeDraw(display, layers);
3110
3111 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 255);
3112 expectBufferColor(Rect(1, 0, 2, 1), 0, 255, 0, 255);
3113}
3114
3115TEST_P(RenderEngineTest, r8_respects_color_transform_when_device_handles) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05003116 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003117 GTEST_SKIP();
3118 }
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003119 initializeRenderEngine();
3120
3121 const auto r8Buffer = allocateR8Buffer(2, 1);
3122 if (!r8Buffer) {
3123 GTEST_SKIP() << "Test is only necessary on devices that support r8";
3124 return;
3125 }
3126 {
3127 uint8_t* pixels;
3128 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
3129 reinterpret_cast<void**>(&pixels));
3130 pixels[0] = 0;
3131 pixels[1] = 255;
3132 r8Buffer->getBuffer()->unlock();
3133 }
3134
3135 const auto rect = Rect(0, 0, 2, 1);
3136 const renderengine::DisplaySettings display{
3137 .physicalDisplay = rect,
3138 .clip = rect,
3139 .outputDataspace = ui::Dataspace::SRGB,
3140 // If deviceHandlesColorTransform is true, pixels where the A8
3141 // buffer is opaque are unaffected. If the colorTransform is
3142 // invertible, pixels where the A8 buffer are transparent have the
3143 // inverse applied to them so that the DPU will convert them back to
3144 // black. Test with an arbitrary, invertible matrix.
3145 .colorTransform = mat4(1, 0, 0, 2,
3146 3, 1, 2, 5,
3147 0, 5, 3, 0,
3148 0, 1, 0, 2),
3149 .deviceHandlesColorTransform = true,
3150 };
3151
3152 const auto redBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(255, 0, 0, 255));
3153 const renderengine::LayerSettings redLayer{
3154 .geometry.boundaries = rect.toFloatRect(),
3155 .source =
3156 renderengine::PixelSource{
3157 .buffer =
3158 renderengine::Buffer{
3159 .buffer = redBuffer,
3160 },
3161 },
3162 .alpha = 1.0f,
3163 };
3164 const renderengine::LayerSettings r8Layer{
3165 .geometry.boundaries = rect.toFloatRect(),
3166 .source =
3167 renderengine::PixelSource{
3168 .buffer =
3169 renderengine::Buffer{
3170 .buffer = r8Buffer,
3171 },
3172 },
3173 .alpha = 1.0f,
3174 };
3175
3176 std::vector<renderengine::LayerSettings> layers{redLayer, r8Layer};
3177 invokeDraw(display, layers);
3178
3179 expectBufferColor(Rect(1, 0, 2, 1), 255, 0, 0, 255); // Still red.
3180 expectBufferColor(Rect(0, 0, 1, 1), 0, 70, 0, 255);
3181}
Leon Scroggins III45be9182022-04-27 10:37:11 -04003182
Alec Mouri0d1a4172024-06-25 23:41:14 +00003183TEST_P(RenderEngineTest, localTonemap_preservesFullscreenSdr) {
3184 if (!GetParam()->apiSupported()) {
3185 GTEST_SKIP();
3186 }
3187
3188 initializeRenderEngine();
3189
3190 mBuffer = std::make_shared<
3191 renderengine::impl::
3192 ExternalTexture>(sp<GraphicBuffer>::make(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1,
3193 GRALLOC_USAGE_SW_READ_OFTEN |
3194 GRALLOC_USAGE_SW_WRITE_OFTEN |
3195 GRALLOC_USAGE_HW_RENDER |
3196 GRALLOC_USAGE_HW_TEXTURE,
3197 "output"),
3198 *mRE,
3199 renderengine::impl::ExternalTexture::Usage::READABLE |
3200 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
3201 ASSERT_EQ(0, mBuffer->getBuffer()->initCheck());
3202
3203 const auto whiteBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(51, 51, 51, 255));
3204
3205 const auto rect = Rect(0, 0, 1, 1);
3206 const renderengine::DisplaySettings display{
3207 .physicalDisplay = rect,
3208 .clip = rect,
3209 .outputDataspace = ui::Dataspace::SRGB,
3210 .targetLuminanceNits = 40,
3211 .tonemapStrategy = renderengine::DisplaySettings::TonemapStrategy::Local,
3212 };
3213
3214 const renderengine::LayerSettings whiteLayer{
3215 .geometry.boundaries = rect.toFloatRect(),
3216 .source =
3217 renderengine::PixelSource{
3218 .buffer =
3219 renderengine::Buffer{
3220 .buffer = whiteBuffer,
3221 },
3222 },
3223 .alpha = 1.0f,
3224 .sourceDataspace = ui::Dataspace::V0_SCRGB_LINEAR,
3225 .whitePointNits = 200,
3226 };
3227
3228 std::vector<renderengine::LayerSettings> layers{whiteLayer};
3229 invokeDraw(display, layers);
3230
3231 expectBufferColor(Rect(0, 0, 1, 1), 255, 255, 255, 255);
3232}
3233
3234TEST_P(RenderEngineTest, localTonemap_preservesFarawaySdrRegions) {
3235 if (!GetParam()->apiSupported()) {
3236 GTEST_SKIP();
3237 }
3238
3239 initializeRenderEngine();
3240
3241 const auto blockWidth = 256;
3242 const auto width = blockWidth * 4;
3243
3244 const auto buffer = allocateSourceBuffer(width, 1);
3245
3246 mBuffer = std::make_shared<
3247 renderengine::impl::
3248 ExternalTexture>(sp<GraphicBuffer>::make(width, 1, HAL_PIXEL_FORMAT_RGBA_8888,
3249 1,
3250 GRALLOC_USAGE_SW_READ_OFTEN |
3251 GRALLOC_USAGE_SW_WRITE_OFTEN |
3252 GRALLOC_USAGE_HW_RENDER |
3253 GRALLOC_USAGE_HW_TEXTURE,
3254 "output"),
3255 *mRE,
3256 renderengine::impl::ExternalTexture::Usage::READABLE |
3257 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
3258
3259 {
3260 uint8_t* pixels;
3261 buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
3262 reinterpret_cast<void**>(&pixels));
3263 uint8_t* dst = pixels;
3264 for (uint32_t i = 0; i < width; i++) {
3265 uint8_t value = 0;
3266 if (i < blockWidth) {
3267 value = 51;
3268 } else if (i >= blockWidth * 3) {
3269 value = 255;
3270 }
3271 dst[0] = value;
3272 dst[1] = value;
3273 dst[2] = value;
3274 dst[3] = 255;
3275 dst += 4;
3276 }
3277 buffer->getBuffer()->unlock();
3278 }
3279
3280 const auto rect = Rect(0, 0, width, 1);
3281 const renderengine::DisplaySettings display{
3282 .physicalDisplay = rect,
3283 .clip = rect,
3284 .outputDataspace = ui::Dataspace::V0_SRGB_LINEAR,
3285 .targetLuminanceNits = 40,
3286 .tonemapStrategy = renderengine::DisplaySettings::TonemapStrategy::Local,
3287 };
3288
3289 const renderengine::LayerSettings whiteLayer{
3290 .geometry.boundaries = rect.toFloatRect(),
3291 .source =
3292 renderengine::PixelSource{
3293 .buffer =
3294 renderengine::Buffer{
3295 .buffer = buffer,
3296 },
3297 },
3298 .alpha = 1.0f,
3299 .sourceDataspace = ui::Dataspace::V0_SCRGB_LINEAR,
3300 .whitePointNits = 200,
3301 };
3302
3303 std::vector<renderengine::LayerSettings> layers{whiteLayer};
3304 invokeDraw(display, layers);
3305
3306 // SDR regions are boosted to preserve SDR detail.
3307 expectBufferColor(Rect(0, 0, blockWidth, 1), 255, 255, 255, 255);
3308 expectBufferColor(Rect(blockWidth, 0, blockWidth * 2, 1), 0, 0, 0, 255);
3309 expectBufferColor(Rect(blockWidth * 2, 0, blockWidth * 3, 1), 0, 0, 0, 255);
3310 expectBufferColor(Rect(blockWidth * 3, 0, blockWidth * 4, 1), 255, 255, 255, 255);
3311}
3312
3313TEST_P(RenderEngineTest, localTonemap_tonemapsNearbySdrRegions) {
3314 if (!GetParam()->apiSupported()) {
3315 GTEST_SKIP();
3316 }
3317
3318 initializeRenderEngine();
3319
3320 const auto blockWidth = 2;
3321 const auto width = blockWidth * 2;
3322
3323 mBuffer = std::make_shared<
3324 renderengine::impl::
3325 ExternalTexture>(sp<GraphicBuffer>::make(width, 1, HAL_PIXEL_FORMAT_RGBA_8888,
3326 1,
3327 GRALLOC_USAGE_SW_READ_OFTEN |
3328 GRALLOC_USAGE_SW_WRITE_OFTEN |
3329 GRALLOC_USAGE_HW_RENDER |
3330 GRALLOC_USAGE_HW_TEXTURE,
3331 "output"),
3332 *mRE,
3333 renderengine::impl::ExternalTexture::Usage::READABLE |
3334 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
3335
3336 const auto buffer = allocateSourceBuffer(width, 1);
3337
3338 {
3339 uint8_t* pixels;
3340 buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
3341 reinterpret_cast<void**>(&pixels));
3342 uint8_t* dst = pixels;
3343 for (uint32_t i = 0; i < width; i++) {
3344 uint8_t value = 0;
3345 if (i < blockWidth) {
3346 value = 51;
3347 } else if (i >= blockWidth) {
3348 value = 255;
3349 }
3350 dst[0] = value;
3351 dst[1] = value;
3352 dst[2] = value;
3353 dst[3] = 255;
3354 dst += 4;
3355 }
3356 buffer->getBuffer()->unlock();
3357 }
3358
3359 const auto rect = Rect(0, 0, width, 1);
3360 const renderengine::DisplaySettings display{
3361 .physicalDisplay = rect,
3362 .clip = rect,
3363 .outputDataspace = ui::Dataspace::V0_SRGB_LINEAR,
3364 .targetLuminanceNits = 40,
3365 .tonemapStrategy = renderengine::DisplaySettings::TonemapStrategy::Local,
3366 };
3367
3368 const renderengine::LayerSettings whiteLayer{
3369 .geometry.boundaries = rect.toFloatRect(),
3370 .source =
3371 renderengine::PixelSource{
3372 .buffer =
3373 renderengine::Buffer{
3374 .buffer = buffer,
3375 },
3376 },
3377 .alpha = 1.0f,
3378 .sourceDataspace = ui::Dataspace::V0_SCRGB_LINEAR,
3379 .whitePointNits = 200,
3380 };
3381
3382 std::vector<renderengine::LayerSettings> layers{whiteLayer};
3383 invokeDraw(display, layers);
3384
3385 // SDR regions remain "dimmed", but preserve detail with a roll-off curve.
3386 expectBufferColor(Rect(0, 0, blockWidth, 1), 132, 132, 132, 255, 2);
3387 // HDR regions are not dimmed.
3388 expectBufferColor(Rect(blockWidth, 0, blockWidth * 2, 1), 255, 255, 255, 255);
3389}
3390
Leon Scroggins III45be9182022-04-27 10:37:11 -04003391TEST_P(RenderEngineTest, primeShaderCache) {
Nolan Scobie195631a2024-03-26 12:22:23 -04003392 // TODO: b/331447071 - Fix in Graphite and re-enable.
3393 if (GetParam()->skiaBackend() == renderengine::RenderEngine::SkiaBackend::GRAPHITE) {
3394 GTEST_SKIP();
3395 }
3396
Leon Scroggins III696bf932024-01-24 15:21:05 -05003397 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003398 GTEST_SKIP();
3399 }
Leon Scroggins III45be9182022-04-27 10:37:11 -04003400 initializeRenderEngine();
3401
Russell Myers3348c742024-04-29 20:22:42 +00003402 PrimeCacheConfig config;
3403 config.cacheUltraHDR = false;
3404 auto fut = mRE->primeCache(config);
Leon Scroggins III45be9182022-04-27 10:37:11 -04003405 if (fut.valid()) {
3406 fut.wait();
3407 }
3408
Alec Mouri47bcb072023-08-15 02:02:49 +00003409 static constexpr int kMinimumExpectedShadersCompiled = 60;
Leon Scroggins III45be9182022-04-27 10:37:11 -04003410 ASSERT_GT(static_cast<skia::SkiaGLRenderEngine*>(mRE.get())->reportShadersCompiled(),
Alec Mouri47bcb072023-08-15 02:02:49 +00003411 kMinimumExpectedShadersCompiled);
Leon Scroggins III45be9182022-04-27 10:37:11 -04003412}
Derek Sollenbergerd3f60652021-06-11 15:34:36 -04003413} // namespace renderengine
Alec Mouri6e57f682018-09-29 20:45:08 -07003414} // namespace android
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08003415
3416// TODO(b/129481165): remove the #pragma below and fix conversion issues
Marin Shalamanovbed7fd32020-12-21 20:02:20 +01003417#pragma clang diagnostic pop // ignored "-Wconversion -Wextra"