blob: b4597e53d1e05d5e24c718de5c3a1004cacd0a23 [file] [log] [blame]
Alec Mouri6e57f682018-09-29 20:45:08 -07001/*
2 * Copyright 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Ana Krulec82ba2ec2020-11-21 13:33:20 -080017#undef LOG_TAG
18#define LOG_TAG "RenderEngineTest"
19
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -080020// TODO(b/129481165): remove the #pragma below and fix conversion issues
21#pragma clang diagnostic push
22#pragma clang diagnostic ignored "-Wconversion"
Marin Shalamanovbed7fd32020-12-21 20:02:20 +010023#pragma clang diagnostic ignored "-Wextra"
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -080024
Lucas Dupin19c8f0e2019-11-25 17:55:44 -080025#include <cutils/properties.h>
Ana Krulec9bc9dc62020-02-26 12:16:40 -080026#include <gtest/gtest.h>
Alec Mouria90a5702021-04-16 16:36:21 +000027#include <renderengine/ExternalTexture.h>
Alec Mouri6e57f682018-09-29 20:45:08 -070028#include <renderengine/RenderEngine.h>
Vishnu Nairdbbe3852022-01-12 20:22:11 -080029#include <renderengine/impl/ExternalTexture.h>
Alec Mouri1089aed2018-10-25 21:33:57 -070030#include <sync/sync.h>
Alec Mouri4049b532021-10-15 20:59:33 -070031#include <system/graphics-base-v1.0.h>
32#include <tonemap/tonemap.h>
33#include <ui/ColorSpace.h>
Alec Mouri6e57f682018-09-29 20:45:08 -070034#include <ui/PixelFormat.h>
Alec Mouric0aae732021-01-12 13:32:18 -080035
36#include <chrono>
37#include <condition_variable>
38#include <fstream>
39
Alec Mouric0aae732021-01-12 13:32:18 -080040#include "../skia/SkiaGLRenderEngine.h"
Ian Elliott1f0911e2022-09-09 16:31:47 -060041#include "../skia/SkiaVkRenderEngine.h"
Ana Krulec9bc9dc62020-02-26 12:16:40 -080042#include "../threaded/RenderEngineThreaded.h"
Alec Mouri6e57f682018-09-29 20:45:08 -070043
Alec Mouri1089aed2018-10-25 21:33:57 -070044constexpr int DEFAULT_DISPLAY_WIDTH = 128;
45constexpr int DEFAULT_DISPLAY_HEIGHT = 256;
46constexpr int DEFAULT_DISPLAY_OFFSET = 64;
Vishnu Nair16efdbf2019-12-10 11:55:42 -080047constexpr bool WRITE_BUFFER_TO_FILE_ON_FAILURE = false;
Alec Mouri1089aed2018-10-25 21:33:57 -070048
Alec Mouri6e57f682018-09-29 20:45:08 -070049namespace android {
Derek Sollenbergerd3f60652021-06-11 15:34:36 -040050namespace renderengine {
Alec Mouri6e57f682018-09-29 20:45:08 -070051
Alec Mouri5a493722022-01-26 16:43:02 -080052namespace {
53
54double EOTF_PQ(double channel) {
55 float m1 = (2610.0 / 4096.0) / 4.0;
56 float m2 = (2523.0 / 4096.0) * 128.0;
57 float c1 = (3424.0 / 4096.0);
58 float c2 = (2413.0 / 4096.0) * 32.0;
59 float c3 = (2392.0 / 4096.0) * 32.0;
60
61 float tmp = std::pow(std::clamp(channel, 0.0, 1.0), 1.0 / m2);
62 tmp = std::fmax(tmp - c1, 0.0) / (c2 - c3 * tmp);
63 return std::pow(tmp, 1.0 / m1);
64}
65
66vec3 EOTF_PQ(vec3 color) {
67 return vec3(EOTF_PQ(color.r), EOTF_PQ(color.g), EOTF_PQ(color.b));
68}
69
70double EOTF_HLG(double channel) {
71 const float a = 0.17883277;
72 const float b = 0.28466892;
73 const float c = 0.55991073;
74 return channel <= 0.5 ? channel * channel / 3.0 : (exp((channel - c) / a) + b) / 12.0;
75}
76
77vec3 EOTF_HLG(vec3 color) {
78 return vec3(EOTF_HLG(color.r), EOTF_HLG(color.g), EOTF_HLG(color.b));
79}
80
81double OETF_sRGB(double channel) {
82 return channel <= 0.0031308 ? channel * 12.92 : (pow(channel, 1.0 / 2.4) * 1.055) - 0.055;
83}
84
85int sign(float in) {
86 return in >= 0.0 ? 1 : -1;
87}
88
89vec3 OETF_sRGB(vec3 linear) {
90 return vec3(sign(linear.r) * OETF_sRGB(linear.r), sign(linear.g) * OETF_sRGB(linear.g),
91 sign(linear.b) * OETF_sRGB(linear.b));
92}
93
Alec Mouri9bcd1d12022-04-21 22:16:56 +000094// clang-format off
95// Converts red channels to green channels, and zeroes out an existing green channel.
96static const auto kRemoveGreenAndMoveRedToGreenMat4 = mat4(0, 1, 0, 0,
97 0, 0, 0, 0,
98 0, 0, 1, 0,
99 0, 0, 0, 1);
100// clang-format on
101
Alec Mouri5a493722022-01-26 16:43:02 -0800102} // namespace
103
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800104class RenderEngineFactory {
105public:
106 virtual ~RenderEngineFactory() = default;
107
108 virtual std::string name() = 0;
Leon Scroggins III696bf932024-01-24 15:21:05 -0500109 virtual renderengine::RenderEngine::GraphicsApi graphicsApi() = 0;
110 virtual bool apiSupported() = 0;
Leon Scroggins III5ef55002024-01-25 10:51:45 -0500111 std::unique_ptr<renderengine::RenderEngine> createRenderEngine() {
112 renderengine::RenderEngineCreationArgs reCreationArgs =
113 renderengine::RenderEngineCreationArgs::Builder()
114 .setPixelFormat(static_cast<int>(ui::PixelFormat::RGBA_8888))
115 .setImageCacheSize(1)
116 .setEnableProtectedContext(false)
117 .setPrecacheToneMapperShaderOnly(false)
118 .setSupportsBackgroundBlur(true)
119 .setContextPriority(renderengine::RenderEngine::ContextPriority::MEDIUM)
Leon Scroggins III696bf932024-01-24 15:21:05 -0500120 .setThreaded(renderengine::RenderEngine::Threaded::NO)
121 .setGraphicsApi(graphicsApi())
Leon Scroggins III5ef55002024-01-25 10:51:45 -0500122 .build();
123 return renderengine::RenderEngine::create(reCreationArgs);
124 }
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800125};
126
Ian Elliott1f0911e2022-09-09 16:31:47 -0600127class SkiaVkRenderEngineFactory : public RenderEngineFactory {
128public:
129 std::string name() override { return "SkiaVkRenderEngineFactory"; }
130
Leon Scroggins III696bf932024-01-24 15:21:05 -0500131 renderengine::RenderEngine::GraphicsApi graphicsApi() override {
132 return renderengine::RenderEngine::GraphicsApi::VK;
Ian Elliott1f0911e2022-09-09 16:31:47 -0600133 }
134
Leon Scroggins III696bf932024-01-24 15:21:05 -0500135 bool apiSupported() override {
Ian Elliott1f0911e2022-09-09 16:31:47 -0600136 return skia::SkiaVkRenderEngine::canSupportSkiaVkRenderEngine();
137 }
Ian Elliott1f0911e2022-09-09 16:31:47 -0600138};
139
Alec Mouri0eab3e82020-12-08 18:10:27 -0800140class SkiaGLESRenderEngineFactory : public RenderEngineFactory {
141public:
Alec Mouric0aae732021-01-12 13:32:18 -0800142 std::string name() override { return "SkiaGLRenderEngineFactory"; }
Alec Mouri0eab3e82020-12-08 18:10:27 -0800143
Leon Scroggins III696bf932024-01-24 15:21:05 -0500144 renderengine::RenderEngine::GraphicsApi graphicsApi() {
145 return renderengine::RenderEngine::GraphicsApi::GL;
Alec Mouric0aae732021-01-12 13:32:18 -0800146 }
147
Leon Scroggins III696bf932024-01-24 15:21:05 -0500148 bool apiSupported() override { return true; }
Alec Mouri0eab3e82020-12-08 18:10:27 -0800149};
150
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800151class RenderEngineTest : public ::testing::TestWithParam<std::shared_ptr<RenderEngineFactory>> {
152public:
Alec Mouria90a5702021-04-16 16:36:21 +0000153 std::shared_ptr<renderengine::ExternalTexture> allocateDefaultBuffer() {
154 return std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800155 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -0700156 ExternalTexture>(sp<GraphicBuffer>::
157 make(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT,
158 HAL_PIXEL_FORMAT_RGBA_8888, 1,
159 GRALLOC_USAGE_SW_READ_OFTEN |
160 GRALLOC_USAGE_SW_WRITE_OFTEN |
161 GRALLOC_USAGE_HW_RENDER |
162 GRALLOC_USAGE_HW_TEXTURE,
163 "output"),
Alec Mouria90a5702021-04-16 16:36:21 +0000164 *mRE,
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800165 renderengine::impl::ExternalTexture::Usage::READABLE |
166 renderengine::impl::ExternalTexture::Usage::
167 WRITEABLE);
Alec Mouri6e57f682018-09-29 20:45:08 -0700168 }
169
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800170 // Allocates a 1x1 buffer to fill with a solid color
Alec Mouria90a5702021-04-16 16:36:21 +0000171 std::shared_ptr<renderengine::ExternalTexture> allocateSourceBuffer(uint32_t width,
172 uint32_t height) {
173 return std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800174 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -0700175 ExternalTexture>(sp<GraphicBuffer>::
176 make(width, height, HAL_PIXEL_FORMAT_RGBA_8888, 1,
177 GRALLOC_USAGE_SW_READ_OFTEN |
178 GRALLOC_USAGE_SW_WRITE_OFTEN |
179 GRALLOC_USAGE_HW_TEXTURE,
180 "input"),
Alec Mouria90a5702021-04-16 16:36:21 +0000181 *mRE,
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800182 renderengine::impl::ExternalTexture::Usage::READABLE |
183 renderengine::impl::ExternalTexture::Usage::
184 WRITEABLE);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800185 }
186
Alec Mouricdf6cbc2021-11-01 17:21:15 -0700187 std::shared_ptr<renderengine::ExternalTexture> allocateAndFillSourceBuffer(uint32_t width,
188 uint32_t height,
189 ubyte4 color) {
190 const auto buffer = allocateSourceBuffer(width, height);
191 uint8_t* pixels;
192 buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
193 reinterpret_cast<void**>(&pixels));
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -0500194 for (uint32_t j = 0; j < height; j++) {
195 uint8_t* dst = pixels + (buffer->getBuffer()->getStride() * j * 4);
196 for (uint32_t i = 0; i < width; i++) {
197 dst[0] = color.r;
198 dst[1] = color.g;
199 dst[2] = color.b;
200 dst[3] = color.a;
201 dst += 4;
202 }
203 }
Alec Mouricdf6cbc2021-11-01 17:21:15 -0700204 buffer->getBuffer()->unlock();
205 return buffer;
206 }
207
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -0500208 std::shared_ptr<renderengine::ExternalTexture> allocateR8Buffer(int width, int height) {
Ady Abrahamd11bade2022-08-01 16:18:03 -0700209 const auto kUsageFlags =
210 static_cast<uint64_t>(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
211 GRALLOC_USAGE_HW_TEXTURE);
212 auto buffer =
213 sp<GraphicBuffer>::make(static_cast<uint32_t>(width), static_cast<uint32_t>(height),
214 android::PIXEL_FORMAT_R_8, 1u, kUsageFlags, "r8");
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -0500215 if (buffer->initCheck() != 0) {
216 // Devices are not required to support R8.
217 return nullptr;
218 }
219 return std::make_shared<
220 renderengine::impl::ExternalTexture>(std::move(buffer), *mRE,
221 renderengine::impl::ExternalTexture::Usage::
222 READABLE);
223 }
224
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800225 RenderEngineTest() {
226 const ::testing::TestInfo* const test_info =
227 ::testing::UnitTest::GetInstance()->current_test_info();
228 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800229 }
Alec Mouri1089aed2018-10-25 21:33:57 -0700230
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800231 ~RenderEngineTest() {
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800232 if (WRITE_BUFFER_TO_FILE_ON_FAILURE && ::testing::Test::HasFailure()) {
233 writeBufferToFile("/data/texture_out_");
234 }
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800235 const ::testing::TestInfo* const test_info =
236 ::testing::UnitTest::GetInstance()->current_test_info();
237 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800238 }
239
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800240 void writeBufferToFile(const char* basename) {
241 std::string filename(basename);
242 filename.append(::testing::UnitTest::GetInstance()->current_test_info()->name());
243 filename.append(".ppm");
244 std::ofstream file(filename.c_str(), std::ios::binary);
245 if (!file.is_open()) {
246 ALOGE("Unable to open file: %s", filename.c_str());
247 ALOGE("You may need to do: \"adb shell setenforce 0\" to enable "
248 "surfaceflinger to write debug images");
249 return;
250 }
251
Alec Mouri1089aed2018-10-25 21:33:57 -0700252 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +0000253 mBuffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
254 reinterpret_cast<void**>(&pixels));
Alec Mouri1089aed2018-10-25 21:33:57 -0700255
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800256 file << "P6\n";
Alec Mouria90a5702021-04-16 16:36:21 +0000257 file << mBuffer->getBuffer()->getWidth() << "\n";
258 file << mBuffer->getBuffer()->getHeight() << "\n";
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800259 file << 255 << "\n";
260
Alec Mouria90a5702021-04-16 16:36:21 +0000261 std::vector<uint8_t> outBuffer(mBuffer->getBuffer()->getWidth() *
262 mBuffer->getBuffer()->getHeight() * 3);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800263 auto outPtr = reinterpret_cast<uint8_t*>(outBuffer.data());
264
Alec Mouria90a5702021-04-16 16:36:21 +0000265 for (int32_t j = 0; j < mBuffer->getBuffer()->getHeight(); j++) {
266 const uint8_t* src = pixels + (mBuffer->getBuffer()->getStride() * j) * 4;
267 for (int32_t i = 0; i < mBuffer->getBuffer()->getWidth(); i++) {
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800268 // Only copy R, G and B components
269 outPtr[0] = src[0];
270 outPtr[1] = src[1];
271 outPtr[2] = src[2];
272 outPtr += 3;
273
274 src += 4;
275 }
276 }
277 file.write(reinterpret_cast<char*>(outBuffer.data()), outBuffer.size());
Alec Mouria90a5702021-04-16 16:36:21 +0000278 mBuffer->getBuffer()->unlock();
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800279 }
280
281 void expectBufferColor(const Region& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
282 size_t c;
283 Rect const* rect = region.getArray(&c);
284 for (size_t i = 0; i < c; i++, rect++) {
285 expectBufferColor(*rect, r, g, b, a);
286 }
287 }
288
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -0400289 void expectBufferColor(const Point& point, uint8_t r, uint8_t g, uint8_t b, uint8_t a,
290 uint8_t tolerance = 0) {
291 expectBufferColor(Rect(point.x, point.y, point.x + 1, point.y + 1), r, g, b, a, tolerance);
292 }
293
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800294 void expectBufferColor(const Rect& rect, uint8_t r, uint8_t g, uint8_t b, uint8_t a,
295 uint8_t tolerance = 0) {
Alec Mouri4049b532021-10-15 20:59:33 -0700296 auto generator = [=](Point) { return ubyte4(r, g, b, a); };
297 expectBufferColor(rect, generator, tolerance);
298 }
299
300 using ColorGenerator = std::function<ubyte4(Point location)>;
301
302 void expectBufferColor(const Rect& rect, ColorGenerator generator, uint8_t tolerance = 0) {
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800303 auto colorCompare = [tolerance](const uint8_t* colorA, const uint8_t* colorB) {
304 auto colorBitCompare = [tolerance](uint8_t a, uint8_t b) {
305 uint8_t tmp = a >= b ? a - b : b - a;
306 return tmp <= tolerance;
307 };
308 return std::equal(colorA, colorA + 4, colorB, colorBitCompare);
Alec Mouri1089aed2018-10-25 21:33:57 -0700309 };
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800310
Alec Mouri4049b532021-10-15 20:59:33 -0700311 expectBufferColor(rect, generator, colorCompare);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800312 }
313
Alec Mouri4049b532021-10-15 20:59:33 -0700314 void expectBufferColor(const Rect& region, ColorGenerator generator,
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800315 std::function<bool(const uint8_t* a, const uint8_t* b)> colorCompare) {
316 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +0000317 mBuffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
318 reinterpret_cast<void**>(&pixels));
Alec Mouri1089aed2018-10-25 21:33:57 -0700319 int32_t maxFails = 10;
320 int32_t fails = 0;
321 for (int32_t j = 0; j < region.getHeight(); j++) {
Alec Mouria90a5702021-04-16 16:36:21 +0000322 const uint8_t* src = pixels +
323 (mBuffer->getBuffer()->getStride() * (region.top + j) + region.left) * 4;
Alec Mouri1089aed2018-10-25 21:33:57 -0700324 for (int32_t i = 0; i < region.getWidth(); i++) {
Alec Mouri4049b532021-10-15 20:59:33 -0700325 const auto location = Point(region.left + i, region.top + j);
326 const ubyte4 colors = generator(location);
327 const uint8_t expected[4] = {colors.r, colors.g, colors.b, colors.a};
328 bool colorMatches = colorCompare(src, expected);
329 EXPECT_TRUE(colorMatches)
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -0400330 << GetParam()->name().c_str() << ": "
Alec Mouri4049b532021-10-15 20:59:33 -0700331 << "pixel @ (" << location.x << ", " << location.y << "): "
332 << "expected (" << static_cast<uint32_t>(colors.r) << ", "
333 << static_cast<uint32_t>(colors.g) << ", "
334 << static_cast<uint32_t>(colors.b) << ", "
335 << static_cast<uint32_t>(colors.a) << "), "
Alec Mouri1089aed2018-10-25 21:33:57 -0700336 << "got (" << static_cast<uint32_t>(src[0]) << ", "
337 << static_cast<uint32_t>(src[1]) << ", " << static_cast<uint32_t>(src[2])
338 << ", " << static_cast<uint32_t>(src[3]) << ")";
339 src += 4;
Alec Mouri4049b532021-10-15 20:59:33 -0700340 if (!colorMatches && ++fails >= maxFails) {
Alec Mouri1089aed2018-10-25 21:33:57 -0700341 break;
342 }
343 }
344 if (fails >= maxFails) {
345 break;
346 }
347 }
Alec Mouria90a5702021-04-16 16:36:21 +0000348 mBuffer->getBuffer()->unlock();
Alec Mouri1089aed2018-10-25 21:33:57 -0700349 }
350
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800351 void expectAlpha(const Rect& rect, uint8_t a) {
Alec Mouri4049b532021-10-15 20:59:33 -0700352 auto generator = [=](Point) { return ubyte4(0, 0, 0, a); };
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800353 auto colorCompare = [](const uint8_t* colorA, const uint8_t* colorB) {
354 return colorA[3] == colorB[3];
355 };
Alec Mouri4049b532021-10-15 20:59:33 -0700356 expectBufferColor(rect, generator, colorCompare);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800357 }
358
359 void expectShadowColor(const renderengine::LayerSettings& castingLayer,
Vishnu Naird9e4f462023-10-06 04:05:45 +0000360 const ShadowSettings& shadow, const ubyte4& casterColor,
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800361 const ubyte4& backgroundColor) {
362 const Rect casterRect(castingLayer.geometry.boundaries);
363 Region casterRegion = Region(casterRect);
Vishnu Nair50c0afe2022-07-11 15:04:07 -0700364 const float casterCornerRadius = (castingLayer.geometry.roundedCornersRadius.x +
365 castingLayer.geometry.roundedCornersRadius.y) /
366 2.0;
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800367 if (casterCornerRadius > 0.0f) {
368 // ignore the corners if a corner radius is set
369 Rect cornerRect(casterCornerRadius, casterCornerRadius);
370 casterRegion.subtractSelf(cornerRect.offsetTo(casterRect.left, casterRect.top));
371 casterRegion.subtractSelf(
372 cornerRect.offsetTo(casterRect.right - casterCornerRadius, casterRect.top));
373 casterRegion.subtractSelf(
374 cornerRect.offsetTo(casterRect.left, casterRect.bottom - casterCornerRadius));
375 casterRegion.subtractSelf(cornerRect.offsetTo(casterRect.right - casterCornerRadius,
376 casterRect.bottom - casterCornerRadius));
377 }
378
379 const float shadowInset = shadow.length * -1.0f;
380 const Rect casterWithShadow =
381 Rect(casterRect).inset(shadowInset, shadowInset, shadowInset, shadowInset);
382 const Region shadowRegion = Region(casterWithShadow).subtractSelf(casterRect);
383 const Region backgroundRegion = Region(fullscreenRect()).subtractSelf(casterWithShadow);
384
385 // verify casting layer
386 expectBufferColor(casterRegion, casterColor.r, casterColor.g, casterColor.b, casterColor.a);
387
388 // verify shadows by testing just the alpha since its difficult to validate the shadow color
389 size_t c;
390 Rect const* r = shadowRegion.getArray(&c);
391 for (size_t i = 0; i < c; i++, r++) {
392 expectAlpha(*r, 255);
393 }
394
395 // verify background
396 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
397 backgroundColor.a);
398 }
399
Vishnu Naird9e4f462023-10-06 04:05:45 +0000400 void expectShadowColorWithoutCaster(const FloatRect& casterBounds, const ShadowSettings& shadow,
Alec Mouribd17b3b2020-12-17 11:08:30 -0800401 const ubyte4& backgroundColor) {
402 const float shadowInset = shadow.length * -1.0f;
403 const Rect casterRect(casterBounds);
404 const Rect shadowRect =
405 Rect(casterRect).inset(shadowInset, shadowInset, shadowInset, shadowInset);
406
407 const Region backgroundRegion =
408 Region(fullscreenRect()).subtractSelf(casterRect).subtractSelf(shadowRect);
409
410 expectAlpha(shadowRect, 255);
411 // (0, 0, 0) fill on the bounds of the layer should be ignored.
412 expectBufferColor(casterRect, 255, 255, 255, 255, 254);
413
414 // verify background
415 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
416 backgroundColor.a);
417 }
418
Vishnu Naird9e4f462023-10-06 04:05:45 +0000419 static ShadowSettings getShadowSettings(const vec2& casterPos, float shadowLength,
420 bool casterIsTranslucent) {
421 ShadowSettings shadow;
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800422 shadow.ambientColor = {0.0f, 0.0f, 0.0f, 0.039f};
423 shadow.spotColor = {0.0f, 0.0f, 0.0f, 0.19f};
424 shadow.lightPos = vec3(casterPos.x, casterPos.y, 0);
425 shadow.lightRadius = 0.0f;
426 shadow.length = shadowLength;
427 shadow.casterIsTranslucent = casterIsTranslucent;
428 return shadow;
429 }
430
Alec Mouri1089aed2018-10-25 21:33:57 -0700431 static Rect fullscreenRect() { return Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT); }
432
433 static Rect offsetRect() {
434 return Rect(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_WIDTH,
435 DEFAULT_DISPLAY_HEIGHT);
436 }
437
438 static Rect offsetRectAtZero() {
439 return Rect(DEFAULT_DISPLAY_WIDTH - DEFAULT_DISPLAY_OFFSET,
440 DEFAULT_DISPLAY_HEIGHT - DEFAULT_DISPLAY_OFFSET);
441 }
442
Sally Qi59a9f502021-10-12 18:53:23 +0000443 void invokeDraw(const renderengine::DisplaySettings& settings,
444 const std::vector<renderengine::LayerSettings>& layers) {
Patrick Williams2e9748f2022-08-09 22:48:18 +0000445 ftl::Future<FenceResult> future =
Alec Mourif29700f2023-08-17 21:53:31 +0000446 mRE->drawLayers(settings, layers, mBuffer, base::unique_fd());
Patrick Williams2e9748f2022-08-09 22:48:18 +0000447 ASSERT_TRUE(future.valid());
Sally Qi59a9f502021-10-12 18:53:23 +0000448
Patrick Williams2e9748f2022-08-09 22:48:18 +0000449 auto result = future.get();
450 ASSERT_TRUE(result.ok());
Alec Mouri1089aed2018-10-25 21:33:57 -0700451
Patrick Williams2e9748f2022-08-09 22:48:18 +0000452 auto fence = result.value();
453 fence->waitForever(LOG_TAG);
Alec Mouri1089aed2018-10-25 21:33:57 -0700454 }
455
Alec Mourid43ccab2019-03-13 12:23:45 -0700456 void drawEmptyLayers() {
Alec Mouri6e57f682018-09-29 20:45:08 -0700457 renderengine::DisplaySettings settings;
Sally Qi59a9f502021-10-12 18:53:23 +0000458 std::vector<renderengine::LayerSettings> layers;
Alec Mouric0aae732021-01-12 13:32:18 -0800459 invokeDraw(settings, layers);
Alec Mouri6e57f682018-09-29 20:45:08 -0700460 }
461
Alec Mouri1089aed2018-10-25 21:33:57 -0700462 template <typename SourceVariant>
463 void fillBuffer(half r, half g, half b, half a);
464
465 template <typename SourceVariant>
466 void fillRedBuffer();
467
468 template <typename SourceVariant>
469 void fillGreenBuffer();
470
471 template <typename SourceVariant>
472 void fillBlueBuffer();
473
474 template <typename SourceVariant>
475 void fillRedTransparentBuffer();
476
477 template <typename SourceVariant>
478 void fillRedOffsetBuffer();
479
480 template <typename SourceVariant>
481 void fillBufferPhysicalOffset();
482
483 template <typename SourceVariant>
Alec Mouri5a6d8572020-03-23 23:56:15 -0700484 void fillBufferCheckers(uint32_t rotation);
Alec Mouri1089aed2018-10-25 21:33:57 -0700485
486 template <typename SourceVariant>
487 void fillBufferCheckersRotate0();
488
489 template <typename SourceVariant>
490 void fillBufferCheckersRotate90();
491
492 template <typename SourceVariant>
493 void fillBufferCheckersRotate180();
494
495 template <typename SourceVariant>
496 void fillBufferCheckersRotate270();
497
498 template <typename SourceVariant>
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800499 void fillBufferWithLayerTransform();
500
501 template <typename SourceVariant>
Alec Mouri1089aed2018-10-25 21:33:57 -0700502 void fillBufferLayerTransform();
503
504 template <typename SourceVariant>
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800505 void fillBufferWithColorTransform();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800506
507 template <typename SourceVariant>
Alec Mouri1089aed2018-10-25 21:33:57 -0700508 void fillBufferColorTransform();
509
Alec Mouri7c94edb2018-12-03 21:23:26 -0800510 template <typename SourceVariant>
Sally Qi2019fd22021-11-22 10:19:04 -0800511 void fillBufferWithColorTransformAndSourceDataspace(const ui::Dataspace sourceDataspace);
512
513 template <typename SourceVariant>
514 void fillBufferColorTransformAndSourceDataspace();
515
516 template <typename SourceVariant>
517 void fillBufferWithColorTransformAndOutputDataspace(const ui::Dataspace outputDataspace);
518
519 template <typename SourceVariant>
520 void fillBufferColorTransformAndOutputDataspace();
521
522 template <typename SourceVariant>
KaiChieh Chuangda2845c2020-12-14 16:49:38 +0800523 void fillBufferWithColorTransformZeroLayerAlpha();
524
525 template <typename SourceVariant>
526 void fillBufferColorTransformZeroLayerAlpha();
527
528 template <typename SourceVariant>
Alec Mouri7c94edb2018-12-03 21:23:26 -0800529 void fillRedBufferWithRoundedCorners();
530
531 template <typename SourceVariant>
532 void fillBufferWithRoundedCorners();
533
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000534 template <typename SourceVariant>
Lucas Dupin19c8f0e2019-11-25 17:55:44 -0800535 void fillBufferAndBlurBackground();
536
537 template <typename SourceVariant>
Alec Mourie8489fd2021-04-29 16:08:56 -0700538 void fillSmallLayerAndBlurBackground();
539
540 template <typename SourceVariant>
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000541 void overlayCorners();
542
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800543 void fillRedBufferTextureTransform();
544
545 void fillBufferTextureTransform();
546
547 void fillRedBufferWithPremultiplyAlpha();
548
549 void fillBufferWithPremultiplyAlpha();
550
551 void fillRedBufferWithoutPremultiplyAlpha();
552
553 void fillBufferWithoutPremultiplyAlpha();
554
Alec Mouriac335532018-11-12 15:01:33 -0800555 void fillGreenColorBufferThenClearRegion();
556
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800557 template <typename SourceVariant>
Vishnu Naird9e4f462023-10-06 04:05:45 +0000558 void drawShadow(const renderengine::LayerSettings& castingLayer, const ShadowSettings& shadow,
559 const ubyte4& casterColor, const ubyte4& backgroundColor);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800560
Vishnu Naird9e4f462023-10-06 04:05:45 +0000561 void drawShadowWithoutCaster(const FloatRect& castingBounds, const ShadowSettings& shadow,
Alec Mouribd17b3b2020-12-17 11:08:30 -0800562 const ubyte4& backgroundColor);
563
Alec Mouri5a493722022-01-26 16:43:02 -0800564 // Tonemaps grey values from sourceDataspace -> Display P3 and checks that GPU and CPU
565 // implementations are identical Also implicitly checks that the injected tonemap shader
566 // compiles
567 void tonemap(ui::Dataspace sourceDataspace, std::function<vec3(vec3)> eotf,
568 std::function<vec3(vec3, float)> scaleOotf);
569
Alec Mouric0aae732021-01-12 13:32:18 -0800570 void initializeRenderEngine();
571
572 std::unique_ptr<renderengine::RenderEngine> mRE;
Alec Mouria90a5702021-04-16 16:36:21 +0000573 std::shared_ptr<renderengine::ExternalTexture> mBuffer;
Alec Mouri6e57f682018-09-29 20:45:08 -0700574};
575
Alec Mouric0aae732021-01-12 13:32:18 -0800576void RenderEngineTest::initializeRenderEngine() {
577 const auto& renderEngineFactory = GetParam();
Alec Mouric16974e2022-09-13 17:35:48 +0000578 mRE = renderEngineFactory->createRenderEngine();
Alec Mouria90a5702021-04-16 16:36:21 +0000579 mBuffer = allocateDefaultBuffer();
Alec Mouric0aae732021-01-12 13:32:18 -0800580}
581
Alec Mouri1089aed2018-10-25 21:33:57 -0700582struct ColorSourceVariant {
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800583 static void fillColor(renderengine::LayerSettings& layer, half r, half g, half b,
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800584 RenderEngineTest* /*fixture*/) {
Alec Mouri1089aed2018-10-25 21:33:57 -0700585 layer.source.solidColor = half3(r, g, b);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800586 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700587 }
588};
589
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800590struct RelaxOpaqueBufferVariant {
591 static void setOpaqueBit(renderengine::LayerSettings& layer) {
592 layer.source.buffer.isOpaque = false;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800593 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800594 }
595
596 static uint8_t getAlphaChannel() { return 255; }
597};
598
599struct ForceOpaqueBufferVariant {
600 static void setOpaqueBit(renderengine::LayerSettings& layer) {
601 layer.source.buffer.isOpaque = true;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800602 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800603 }
604
605 static uint8_t getAlphaChannel() {
606 // The isOpaque bit will override the alpha channel, so this should be
607 // arbitrary.
Alec Mouric0aae732021-01-12 13:32:18 -0800608 return 50;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800609 }
610};
611
612template <typename OpaquenessVariant>
613struct BufferSourceVariant {
614 static void fillColor(renderengine::LayerSettings& layer, half r, half g, half b,
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800615 RenderEngineTest* fixture) {
Alec Mouria90a5702021-04-16 16:36:21 +0000616 const auto buf = fixture->allocateSourceBuffer(1, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800617
618 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +0000619 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
620 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800621
Alec Mouria90a5702021-04-16 16:36:21 +0000622 for (int32_t j = 0; j < buf->getBuffer()->getHeight(); j++) {
623 uint8_t* iter = pixels + (buf->getBuffer()->getStride() * j) * 4;
624 for (int32_t i = 0; i < buf->getBuffer()->getWidth(); i++) {
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800625 iter[0] = uint8_t(r * 255);
626 iter[1] = uint8_t(g * 255);
627 iter[2] = uint8_t(b * 255);
628 iter[3] = OpaquenessVariant::getAlphaChannel();
629 iter += 4;
630 }
631 }
632
Alec Mouria90a5702021-04-16 16:36:21 +0000633 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800634
635 layer.source.buffer.buffer = buf;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800636 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800637 OpaquenessVariant::setOpaqueBit(layer);
638 }
639};
640
Alec Mouri1089aed2018-10-25 21:33:57 -0700641template <typename SourceVariant>
642void RenderEngineTest::fillBuffer(half r, half g, half b, half a) {
643 renderengine::DisplaySettings settings;
644 settings.physicalDisplay = fullscreenRect();
645 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800646 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700647
Sally Qi59a9f502021-10-12 18:53:23 +0000648 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700649
650 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800651 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700652 layer.geometry.boundaries = fullscreenRect().toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800653 SourceVariant::fillColor(layer, r, g, b, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700654 layer.alpha = a;
655
Sally Qi59a9f502021-10-12 18:53:23 +0000656 layers.push_back(layer);
Alec Mouri1089aed2018-10-25 21:33:57 -0700657
Alec Mouric0aae732021-01-12 13:32:18 -0800658 invokeDraw(settings, layers);
Alec Mouri1089aed2018-10-25 21:33:57 -0700659}
660
661template <typename SourceVariant>
662void RenderEngineTest::fillRedBuffer() {
663 fillBuffer<SourceVariant>(1.0f, 0.0f, 0.0f, 1.0f);
664 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
665}
666
667template <typename SourceVariant>
668void RenderEngineTest::fillGreenBuffer() {
669 fillBuffer<SourceVariant>(0.0f, 1.0f, 0.0f, 1.0f);
670 expectBufferColor(fullscreenRect(), 0, 255, 0, 255);
671}
672
673template <typename SourceVariant>
674void RenderEngineTest::fillBlueBuffer() {
675 fillBuffer<SourceVariant>(0.0f, 0.0f, 1.0f, 1.0f);
676 expectBufferColor(fullscreenRect(), 0, 0, 255, 255);
677}
678
679template <typename SourceVariant>
680void RenderEngineTest::fillRedTransparentBuffer() {
681 fillBuffer<SourceVariant>(1.0f, 0.0f, 0.0f, .2f);
682 expectBufferColor(fullscreenRect(), 51, 0, 0, 51);
683}
684
685template <typename SourceVariant>
686void RenderEngineTest::fillRedOffsetBuffer() {
687 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800688 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700689 settings.physicalDisplay = offsetRect();
690 settings.clip = offsetRectAtZero();
691
Sally Qi59a9f502021-10-12 18:53:23 +0000692 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700693
694 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800695 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700696 layer.geometry.boundaries = offsetRectAtZero().toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800697 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700698 layer.alpha = 1.0f;
699
Sally Qi59a9f502021-10-12 18:53:23 +0000700 layers.push_back(layer);
Alec Mouric0aae732021-01-12 13:32:18 -0800701 invokeDraw(settings, layers);
Alec Mouri1089aed2018-10-25 21:33:57 -0700702}
703
704template <typename SourceVariant>
705void RenderEngineTest::fillBufferPhysicalOffset() {
706 fillRedOffsetBuffer<SourceVariant>();
707
708 expectBufferColor(Rect(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_WIDTH,
709 DEFAULT_DISPLAY_HEIGHT),
710 255, 0, 0, 255);
711 Rect offsetRegionLeft(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_HEIGHT);
712 Rect offsetRegionTop(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_OFFSET);
713
714 expectBufferColor(offsetRegionLeft, 0, 0, 0, 0);
715 expectBufferColor(offsetRegionTop, 0, 0, 0, 0);
716}
717
718template <typename SourceVariant>
Alec Mouri5a6d8572020-03-23 23:56:15 -0700719void RenderEngineTest::fillBufferCheckers(uint32_t orientationFlag) {
Alec Mouri1089aed2018-10-25 21:33:57 -0700720 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800721 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700722 settings.physicalDisplay = fullscreenRect();
723 // Here logical space is 2x2
724 settings.clip = Rect(2, 2);
Alec Mouri5a6d8572020-03-23 23:56:15 -0700725 settings.orientation = orientationFlag;
Alec Mouri1089aed2018-10-25 21:33:57 -0700726
Sally Qi59a9f502021-10-12 18:53:23 +0000727 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700728
729 renderengine::LayerSettings layerOne;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800730 layerOne.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700731 Rect rectOne(0, 0, 1, 1);
732 layerOne.geometry.boundaries = rectOne.toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800733 SourceVariant::fillColor(layerOne, 1.0f, 0.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700734 layerOne.alpha = 1.0f;
735
736 renderengine::LayerSettings layerTwo;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800737 layerTwo.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700738 Rect rectTwo(0, 1, 1, 2);
739 layerTwo.geometry.boundaries = rectTwo.toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800740 SourceVariant::fillColor(layerTwo, 0.0f, 1.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700741 layerTwo.alpha = 1.0f;
742
743 renderengine::LayerSettings layerThree;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800744 layerThree.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700745 Rect rectThree(1, 0, 2, 1);
746 layerThree.geometry.boundaries = rectThree.toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800747 SourceVariant::fillColor(layerThree, 0.0f, 0.0f, 1.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700748 layerThree.alpha = 1.0f;
749
Sally Qi59a9f502021-10-12 18:53:23 +0000750 layers.push_back(layerOne);
751 layers.push_back(layerTwo);
752 layers.push_back(layerThree);
Alec Mouri1089aed2018-10-25 21:33:57 -0700753
Alec Mouric0aae732021-01-12 13:32:18 -0800754 invokeDraw(settings, layers);
Alec Mouri1089aed2018-10-25 21:33:57 -0700755}
756
757template <typename SourceVariant>
758void RenderEngineTest::fillBufferCheckersRotate0() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700759 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_0);
Alec Mouri1089aed2018-10-25 21:33:57 -0700760 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0,
761 255);
762 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
763 DEFAULT_DISPLAY_HEIGHT / 2),
764 0, 0, 255, 255);
765 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
766 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
767 0, 0, 0, 0);
768 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
769 DEFAULT_DISPLAY_HEIGHT),
770 0, 255, 0, 255);
771}
772
773template <typename SourceVariant>
774void RenderEngineTest::fillBufferCheckersRotate90() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700775 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_90);
Alec Mouri1089aed2018-10-25 21:33:57 -0700776 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 255, 0,
777 255);
778 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
779 DEFAULT_DISPLAY_HEIGHT / 2),
780 255, 0, 0, 255);
781 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
782 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
783 0, 0, 255, 255);
784 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
785 DEFAULT_DISPLAY_HEIGHT),
786 0, 0, 0, 0);
787}
788
789template <typename SourceVariant>
790void RenderEngineTest::fillBufferCheckersRotate180() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700791 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_180);
Alec Mouri1089aed2018-10-25 21:33:57 -0700792 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 0,
793 0);
794 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
795 DEFAULT_DISPLAY_HEIGHT / 2),
796 0, 255, 0, 255);
797 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
798 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
799 255, 0, 0, 255);
800 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
801 DEFAULT_DISPLAY_HEIGHT),
802 0, 0, 255, 255);
803}
804
805template <typename SourceVariant>
806void RenderEngineTest::fillBufferCheckersRotate270() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700807 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_270);
Alec Mouri1089aed2018-10-25 21:33:57 -0700808 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 255,
809 255);
810 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
811 DEFAULT_DISPLAY_HEIGHT / 2),
812 0, 0, 0, 0);
813 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
814 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
815 0, 255, 0, 255);
816 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
817 DEFAULT_DISPLAY_HEIGHT),
818 255, 0, 0, 255);
819}
820
821template <typename SourceVariant>
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800822void RenderEngineTest::fillBufferWithLayerTransform() {
Alec Mouri1089aed2018-10-25 21:33:57 -0700823 renderengine::DisplaySettings settings;
824 settings.physicalDisplay = fullscreenRect();
825 // Here logical space is 2x2
826 settings.clip = Rect(2, 2);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800827 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700828
Sally Qi59a9f502021-10-12 18:53:23 +0000829 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700830
831 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800832 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700833 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
834 // Translate one pixel diagonally
835 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 -0800836 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700837 layer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
838 layer.alpha = 1.0f;
839
Sally Qi59a9f502021-10-12 18:53:23 +0000840 layers.push_back(layer);
Alec Mouri1089aed2018-10-25 21:33:57 -0700841
Alec Mouric0aae732021-01-12 13:32:18 -0800842 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800843}
Alec Mouri1089aed2018-10-25 21:33:57 -0700844
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800845template <typename SourceVariant>
846void RenderEngineTest::fillBufferLayerTransform() {
847 fillBufferWithLayerTransform<SourceVariant>();
Alec Mouri1089aed2018-10-25 21:33:57 -0700848 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 0, 0);
849 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
850 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
851 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
852 255, 0, 0, 255);
853}
854
855template <typename SourceVariant>
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800856void RenderEngineTest::fillBufferWithColorTransform() {
Alec Mouri1089aed2018-10-25 21:33:57 -0700857 renderengine::DisplaySettings settings;
858 settings.physicalDisplay = fullscreenRect();
859 settings.clip = Rect(1, 1);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800860 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700861
Sally Qi59a9f502021-10-12 18:53:23 +0000862 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700863
864 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800865 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700866 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800867 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700868 layer.alpha = 1.0f;
869
870 // construct a fake color matrix
871 // annihilate green and blue channels
KaiChieh Chuang436fc192020-09-07 13:48:42 +0800872 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
Alec Mouri1089aed2018-10-25 21:33:57 -0700873 // set red channel to red + green
874 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
875
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800876 layer.alpha = 1.0f;
877 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
878
Sally Qi59a9f502021-10-12 18:53:23 +0000879 layers.push_back(layer);
Alec Mouri1089aed2018-10-25 21:33:57 -0700880
Alec Mouric0aae732021-01-12 13:32:18 -0800881 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800882}
Alec Mouri1089aed2018-10-25 21:33:57 -0700883
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800884template <typename SourceVariant>
Sally Qi2019fd22021-11-22 10:19:04 -0800885void RenderEngineTest::fillBufferWithColorTransformAndSourceDataspace(
886 const ui::Dataspace sourceDataspace) {
887 renderengine::DisplaySettings settings;
888 settings.physicalDisplay = fullscreenRect();
889 settings.clip = Rect(1, 1);
890 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
891
892 std::vector<renderengine::LayerSettings> layers;
893
894 renderengine::LayerSettings layer;
Sally Qi2019fd22021-11-22 10:19:04 -0800895 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
896 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
Alec Mouric16974e2022-09-13 17:35:48 +0000897 layer.sourceDataspace = sourceDataspace;
Sally Qi2019fd22021-11-22 10:19:04 -0800898 layer.alpha = 1.0f;
899
900 // construct a fake color matrix
901 // annihilate green and blue channels
902 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
903 // set red channel to red + green
904 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
905
906 layer.alpha = 1.0f;
907 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
908
909 layers.push_back(layer);
910
911 invokeDraw(settings, layers);
912}
913
914template <typename SourceVariant>
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800915void RenderEngineTest::fillBufferColorTransform() {
916 fillBufferWithColorTransform<SourceVariant>();
KaiChieh Chuang436fc192020-09-07 13:48:42 +0800917 expectBufferColor(fullscreenRect(), 172, 0, 0, 255, 1);
918}
919
920template <typename SourceVariant>
Sally Qi2019fd22021-11-22 10:19:04 -0800921void RenderEngineTest::fillBufferColorTransformAndSourceDataspace() {
922 unordered_map<ui::Dataspace, ubyte4> dataspaceToColorMap;
Alec Mouric16974e2022-09-13 17:35:48 +0000923 dataspaceToColorMap[ui::Dataspace::V0_BT709] = {77, 0, 0, 255};
924 dataspaceToColorMap[ui::Dataspace::BT2020] = {101, 0, 0, 255};
925 dataspaceToColorMap[ui::Dataspace::ADOBE_RGB] = {75, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -0800926 ui::Dataspace customizedDataspace = static_cast<ui::Dataspace>(
927 ui::Dataspace::STANDARD_BT709 | ui::Dataspace::TRANSFER_GAMMA2_2 |
928 ui::Dataspace::RANGE_FULL);
Alec Mouric16974e2022-09-13 17:35:48 +0000929 dataspaceToColorMap[customizedDataspace] = {61, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -0800930 for (const auto& [sourceDataspace, color] : dataspaceToColorMap) {
931 fillBufferWithColorTransformAndSourceDataspace<SourceVariant>(sourceDataspace);
932 expectBufferColor(fullscreenRect(), color.r, color.g, color.b, color.a, 1);
933 }
934}
935
936template <typename SourceVariant>
937void RenderEngineTest::fillBufferWithColorTransformAndOutputDataspace(
938 const ui::Dataspace outputDataspace) {
939 renderengine::DisplaySettings settings;
940 settings.physicalDisplay = fullscreenRect();
941 settings.clip = Rect(1, 1);
942 settings.outputDataspace = outputDataspace;
943
944 std::vector<renderengine::LayerSettings> layers;
945
946 renderengine::LayerSettings layer;
947 layer.sourceDataspace = ui::Dataspace::V0_SCRGB_LINEAR;
948 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
949 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
950 layer.alpha = 1.0f;
951
952 // construct a fake color matrix
953 // annihilate green and blue channels
954 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
955 // set red channel to red + green
956 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
957
958 layer.alpha = 1.0f;
959 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
960
961 layers.push_back(layer);
962
963 invokeDraw(settings, layers);
964}
965
966template <typename SourceVariant>
967void RenderEngineTest::fillBufferColorTransformAndOutputDataspace() {
968 unordered_map<ui::Dataspace, ubyte4> dataspaceToColorMap;
Alec Mouric16974e2022-09-13 17:35:48 +0000969 dataspaceToColorMap[ui::Dataspace::V0_BT709] = {198, 0, 0, 255};
970 dataspaceToColorMap[ui::Dataspace::BT2020] = {187, 0, 0, 255};
971 dataspaceToColorMap[ui::Dataspace::ADOBE_RGB] = {192, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -0800972 ui::Dataspace customizedDataspace = static_cast<ui::Dataspace>(
973 ui::Dataspace::STANDARD_BT709 | ui::Dataspace::TRANSFER_GAMMA2_6 |
974 ui::Dataspace::RANGE_FULL);
Alec Mouric16974e2022-09-13 17:35:48 +0000975 dataspaceToColorMap[customizedDataspace] = {205, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -0800976 for (const auto& [outputDataspace, color] : dataspaceToColorMap) {
977 fillBufferWithColorTransformAndOutputDataspace<SourceVariant>(outputDataspace);
978 expectBufferColor(fullscreenRect(), color.r, color.g, color.b, color.a, 1);
979 }
980}
981
982template <typename SourceVariant>
KaiChieh Chuangda2845c2020-12-14 16:49:38 +0800983void RenderEngineTest::fillBufferWithColorTransformZeroLayerAlpha() {
984 renderengine::DisplaySettings settings;
985 settings.physicalDisplay = fullscreenRect();
986 settings.clip = Rect(1, 1);
987
Sally Qi59a9f502021-10-12 18:53:23 +0000988 std::vector<renderengine::LayerSettings> layers;
KaiChieh Chuangda2845c2020-12-14 16:49:38 +0800989
990 renderengine::LayerSettings layer;
991 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
992 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
993 layer.alpha = 0;
994
995 // construct a fake color matrix
996 // simple inverse color
997 settings.colorTransform = mat4(-1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 1, 1, 1, 1);
998
999 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1000
Sally Qi59a9f502021-10-12 18:53:23 +00001001 layers.push_back(layer);
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001002
Alec Mouric0aae732021-01-12 13:32:18 -08001003 invokeDraw(settings, layers);
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001004}
1005
1006template <typename SourceVariant>
1007void RenderEngineTest::fillBufferColorTransformZeroLayerAlpha() {
1008 fillBufferWithColorTransformZeroLayerAlpha<SourceVariant>();
1009 expectBufferColor(fullscreenRect(), 0, 0, 0, 0);
1010}
1011
1012template <typename SourceVariant>
Alec Mouri7c94edb2018-12-03 21:23:26 -08001013void RenderEngineTest::fillRedBufferWithRoundedCorners() {
1014 renderengine::DisplaySettings settings;
1015 settings.physicalDisplay = fullscreenRect();
1016 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001017 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri7c94edb2018-12-03 21:23:26 -08001018
Sally Qi59a9f502021-10-12 18:53:23 +00001019 std::vector<renderengine::LayerSettings> layers;
Alec Mouri7c94edb2018-12-03 21:23:26 -08001020
1021 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001022 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri7c94edb2018-12-03 21:23:26 -08001023 layer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07001024 layer.geometry.roundedCornersRadius = {5.0f, 5.0f};
Alec Mouri7c94edb2018-12-03 21:23:26 -08001025 layer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
1026 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
1027 layer.alpha = 1.0f;
1028
Sally Qi59a9f502021-10-12 18:53:23 +00001029 layers.push_back(layer);
Alec Mouri7c94edb2018-12-03 21:23:26 -08001030
Alec Mouric0aae732021-01-12 13:32:18 -08001031 invokeDraw(settings, layers);
Alec Mouri7c94edb2018-12-03 21:23:26 -08001032}
1033
1034template <typename SourceVariant>
1035void RenderEngineTest::fillBufferWithRoundedCorners() {
1036 fillRedBufferWithRoundedCorners<SourceVariant>();
1037 // Corners should be ignored...
1038 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 0);
1039 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, 0, DEFAULT_DISPLAY_WIDTH, 1), 0, 0, 0, 0);
1040 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT - 1, 1, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
1041 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1,
1042 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1043 0, 0, 0, 0);
1044 // ...And the non-rounded portion should be red.
1045 // Other pixels may be anti-aliased, so let's not check those.
1046 expectBufferColor(Rect(5, 5, DEFAULT_DISPLAY_WIDTH - 5, DEFAULT_DISPLAY_HEIGHT - 5), 255, 0, 0,
1047 255);
1048}
1049
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001050template <typename SourceVariant>
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001051void RenderEngineTest::fillBufferAndBlurBackground() {
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001052 auto blurRadius = 50;
1053 auto center = DEFAULT_DISPLAY_WIDTH / 2;
1054
1055 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001056 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001057 settings.physicalDisplay = fullscreenRect();
1058 settings.clip = fullscreenRect();
1059
Sally Qi59a9f502021-10-12 18:53:23 +00001060 std::vector<renderengine::LayerSettings> layers;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001061
1062 renderengine::LayerSettings backgroundLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001063 backgroundLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001064 backgroundLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1065 SourceVariant::fillColor(backgroundLayer, 0.0f, 1.0f, 0.0f, this);
1066 backgroundLayer.alpha = 1.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001067 layers.emplace_back(backgroundLayer);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001068
1069 renderengine::LayerSettings leftLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001070 leftLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001071 leftLayer.geometry.boundaries =
1072 Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT).toFloatRect();
1073 SourceVariant::fillColor(leftLayer, 1.0f, 0.0f, 0.0f, this);
1074 leftLayer.alpha = 1.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001075 layers.emplace_back(leftLayer);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001076
1077 renderengine::LayerSettings blurLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001078 blurLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001079 blurLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1080 blurLayer.backgroundBlurRadius = blurRadius;
Derek Sollenbergerecb21462021-01-29 16:53:49 -05001081 SourceVariant::fillColor(blurLayer, 0.0f, 0.0f, 1.0f, this);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001082 blurLayer.alpha = 0;
Sally Qi59a9f502021-10-12 18:53:23 +00001083 layers.emplace_back(blurLayer);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001084
Alec Mouric0aae732021-01-12 13:32:18 -08001085 invokeDraw(settings, layers);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001086
Derek Sollenbergerecb21462021-01-29 16:53:49 -05001087 // solid color
1088 expectBufferColor(Rect(0, 0, 1, 1), 255, 0, 0, 255, 0 /* tolerance */);
1089
Derek Sollenbergerb3998372021-02-16 15:16:56 -05001090 if (mRE->supportsBackgroundBlur()) {
1091 // blurred color (downsampling should result in the center color being close to 128)
1092 expectBufferColor(Rect(center - 1, center - 5, center + 1, center + 5), 128, 128, 0, 255,
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001093 50 /* tolerance */);
Derek Sollenbergerb3998372021-02-16 15:16:56 -05001094 }
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001095}
1096
1097template <typename SourceVariant>
Alec Mourie8489fd2021-04-29 16:08:56 -07001098void RenderEngineTest::fillSmallLayerAndBlurBackground() {
1099 auto blurRadius = 50;
1100 renderengine::DisplaySettings settings;
1101 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1102 settings.physicalDisplay = fullscreenRect();
1103 settings.clip = fullscreenRect();
1104
Sally Qi59a9f502021-10-12 18:53:23 +00001105 std::vector<renderengine::LayerSettings> layers;
Alec Mourie8489fd2021-04-29 16:08:56 -07001106
1107 renderengine::LayerSettings backgroundLayer;
1108 backgroundLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1109 backgroundLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1110 SourceVariant::fillColor(backgroundLayer, 1.0f, 0.0f, 0.0f, this);
1111 backgroundLayer.alpha = 1.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001112 layers.push_back(backgroundLayer);
Alec Mourie8489fd2021-04-29 16:08:56 -07001113
1114 renderengine::LayerSettings blurLayer;
1115 blurLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1116 blurLayer.geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f);
1117 blurLayer.backgroundBlurRadius = blurRadius;
1118 SourceVariant::fillColor(blurLayer, 0.0f, 0.0f, 1.0f, this);
1119 blurLayer.alpha = 0;
Sally Qi59a9f502021-10-12 18:53:23 +00001120 layers.push_back(blurLayer);
Alec Mourie8489fd2021-04-29 16:08:56 -07001121
1122 invokeDraw(settings, layers);
1123
1124 // Give a generous tolerance - the blur rectangle is very small and this test is
1125 // mainly concerned with ensuring that there's no device failure.
1126 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT), 255, 0, 0, 255,
1127 40 /* tolerance */);
1128}
1129
1130template <typename SourceVariant>
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001131void RenderEngineTest::overlayCorners() {
1132 renderengine::DisplaySettings settings;
1133 settings.physicalDisplay = fullscreenRect();
1134 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001135 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001136
Sally Qi59a9f502021-10-12 18:53:23 +00001137 std::vector<renderengine::LayerSettings> layersFirst;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001138
1139 renderengine::LayerSettings layerOne;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001140 layerOne.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001141 layerOne.geometry.boundaries =
1142 FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH / 3.0, DEFAULT_DISPLAY_HEIGHT / 3.0);
1143 SourceVariant::fillColor(layerOne, 1.0f, 0.0f, 0.0f, this);
1144 layerOne.alpha = 0.2;
1145
Sally Qi59a9f502021-10-12 18:53:23 +00001146 layersFirst.push_back(layerOne);
Alec Mouric0aae732021-01-12 13:32:18 -08001147 invokeDraw(settings, layersFirst);
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001148 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3), 51, 0, 0, 51);
1149 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3 + 1, DEFAULT_DISPLAY_HEIGHT / 3 + 1,
1150 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1151 0, 0, 0, 0);
1152
Sally Qi59a9f502021-10-12 18:53:23 +00001153 std::vector<renderengine::LayerSettings> layersSecond;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001154 renderengine::LayerSettings layerTwo;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001155 layerTwo.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001156 layerTwo.geometry.boundaries =
1157 FloatRect(DEFAULT_DISPLAY_WIDTH / 3.0, DEFAULT_DISPLAY_HEIGHT / 3.0,
1158 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT);
1159 SourceVariant::fillColor(layerTwo, 0.0f, 1.0f, 0.0f, this);
1160 layerTwo.alpha = 1.0f;
1161
Sally Qi59a9f502021-10-12 18:53:23 +00001162 layersSecond.push_back(layerTwo);
Alec Mouric0aae732021-01-12 13:32:18 -08001163 invokeDraw(settings, layersSecond);
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001164
1165 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3), 0, 0, 0, 0);
1166 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3 + 1, DEFAULT_DISPLAY_HEIGHT / 3 + 1,
1167 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1168 0, 255, 0, 255);
1169}
1170
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001171void RenderEngineTest::fillRedBufferTextureTransform() {
1172 renderengine::DisplaySettings settings;
1173 settings.physicalDisplay = fullscreenRect();
1174 settings.clip = Rect(1, 1);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001175 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001176
Sally Qi59a9f502021-10-12 18:53:23 +00001177 std::vector<renderengine::LayerSettings> layers;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001178
1179 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001180 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001181 // Here will allocate a checker board texture, but transform texture
1182 // coordinates so that only the upper left is applied.
Alec Mouria90a5702021-04-16 16:36:21 +00001183 const auto buf = allocateSourceBuffer(2, 2);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001184
1185 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00001186 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1187 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001188 // Red top left, Green top right, Blue bottom left, Black bottom right
1189 pixels[0] = 255;
1190 pixels[1] = 0;
1191 pixels[2] = 0;
1192 pixels[3] = 255;
1193 pixels[4] = 0;
1194 pixels[5] = 255;
1195 pixels[6] = 0;
1196 pixels[7] = 255;
1197 pixels[8] = 0;
1198 pixels[9] = 0;
1199 pixels[10] = 255;
1200 pixels[11] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00001201 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001202
1203 layer.source.buffer.buffer = buf;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001204 // Transform coordinates to only be inside the red quadrant.
Alec Mouri4049b532021-10-15 20:59:33 -07001205 layer.source.buffer.textureTransform = mat4::scale(vec4(0.2f, 0.2f, 1.f, 1.f));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001206 layer.alpha = 1.0f;
1207 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1208
Sally Qi59a9f502021-10-12 18:53:23 +00001209 layers.push_back(layer);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001210
Alec Mouric0aae732021-01-12 13:32:18 -08001211 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001212}
1213
1214void RenderEngineTest::fillBufferTextureTransform() {
1215 fillRedBufferTextureTransform();
1216 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
1217}
1218
1219void RenderEngineTest::fillRedBufferWithPremultiplyAlpha() {
1220 renderengine::DisplaySettings settings;
1221 settings.physicalDisplay = fullscreenRect();
1222 // Here logical space is 1x1
1223 settings.clip = Rect(1, 1);
1224
Sally Qi59a9f502021-10-12 18:53:23 +00001225 std::vector<renderengine::LayerSettings> layers;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001226
1227 renderengine::LayerSettings layer;
Alec Mouria90a5702021-04-16 16:36:21 +00001228 const auto buf = allocateSourceBuffer(1, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001229
1230 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00001231 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1232 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001233 pixels[0] = 255;
1234 pixels[1] = 0;
1235 pixels[2] = 0;
1236 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00001237 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001238
1239 layer.source.buffer.buffer = buf;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001240 layer.source.buffer.usePremultipliedAlpha = true;
1241 layer.alpha = 0.5f;
1242 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1243
Sally Qi59a9f502021-10-12 18:53:23 +00001244 layers.push_back(layer);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001245
Alec Mouric0aae732021-01-12 13:32:18 -08001246 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001247}
1248
1249void RenderEngineTest::fillBufferWithPremultiplyAlpha() {
1250 fillRedBufferWithPremultiplyAlpha();
1251 expectBufferColor(fullscreenRect(), 128, 0, 0, 128);
1252}
1253
1254void RenderEngineTest::fillRedBufferWithoutPremultiplyAlpha() {
1255 renderengine::DisplaySettings settings;
1256 settings.physicalDisplay = fullscreenRect();
1257 // Here logical space is 1x1
1258 settings.clip = Rect(1, 1);
1259
Sally Qi59a9f502021-10-12 18:53:23 +00001260 std::vector<renderengine::LayerSettings> layers;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001261
1262 renderengine::LayerSettings layer;
Alec Mouria90a5702021-04-16 16:36:21 +00001263 const auto buf = allocateSourceBuffer(1, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001264
1265 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00001266 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1267 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001268 pixels[0] = 255;
1269 pixels[1] = 0;
1270 pixels[2] = 0;
1271 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00001272 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001273
1274 layer.source.buffer.buffer = buf;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001275 layer.source.buffer.usePremultipliedAlpha = false;
1276 layer.alpha = 0.5f;
1277 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1278
Sally Qi59a9f502021-10-12 18:53:23 +00001279 layers.push_back(layer);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001280
Alec Mouric0aae732021-01-12 13:32:18 -08001281 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001282}
1283
1284void RenderEngineTest::fillBufferWithoutPremultiplyAlpha() {
1285 fillRedBufferWithoutPremultiplyAlpha();
wukui16f3c0bb2020-08-05 20:35:29 +08001286 expectBufferColor(fullscreenRect(), 128, 0, 0, 128, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001287}
1288
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001289template <typename SourceVariant>
1290void RenderEngineTest::drawShadow(const renderengine::LayerSettings& castingLayer,
Vishnu Naird9e4f462023-10-06 04:05:45 +00001291 const ShadowSettings& shadow, const ubyte4& casterColor,
1292 const ubyte4& backgroundColor) {
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001293 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001294 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001295 settings.physicalDisplay = fullscreenRect();
1296 settings.clip = fullscreenRect();
1297
Sally Qi59a9f502021-10-12 18:53:23 +00001298 std::vector<renderengine::LayerSettings> layers;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001299
1300 // add background layer
1301 renderengine::LayerSettings bgLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001302 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001303 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1304 ColorSourceVariant::fillColor(bgLayer, backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1305 backgroundColor.b / 255.0f, this);
1306 bgLayer.alpha = backgroundColor.a / 255.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001307 layers.push_back(bgLayer);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001308
1309 // add shadow layer
1310 renderengine::LayerSettings shadowLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001311 shadowLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001312 shadowLayer.geometry.boundaries = castingLayer.geometry.boundaries;
1313 shadowLayer.alpha = castingLayer.alpha;
1314 shadowLayer.shadow = shadow;
Sally Qi59a9f502021-10-12 18:53:23 +00001315 layers.push_back(shadowLayer);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001316
1317 // add layer casting the shadow
1318 renderengine::LayerSettings layer = castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001319 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001320 SourceVariant::fillColor(layer, casterColor.r / 255.0f, casterColor.g / 255.0f,
1321 casterColor.b / 255.0f, this);
Sally Qi59a9f502021-10-12 18:53:23 +00001322 layers.push_back(layer);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001323
Alec Mouric0aae732021-01-12 13:32:18 -08001324 invokeDraw(settings, layers);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001325}
1326
Alec Mouribd17b3b2020-12-17 11:08:30 -08001327void RenderEngineTest::drawShadowWithoutCaster(const FloatRect& castingBounds,
Vishnu Naird9e4f462023-10-06 04:05:45 +00001328 const ShadowSettings& shadow,
Alec Mouribd17b3b2020-12-17 11:08:30 -08001329 const ubyte4& backgroundColor) {
1330 renderengine::DisplaySettings settings;
1331 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1332 settings.physicalDisplay = fullscreenRect();
1333 settings.clip = fullscreenRect();
1334
Sally Qi59a9f502021-10-12 18:53:23 +00001335 std::vector<renderengine::LayerSettings> layers;
Alec Mouribd17b3b2020-12-17 11:08:30 -08001336
1337 // add background layer
1338 renderengine::LayerSettings bgLayer;
1339 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1340 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1341 ColorSourceVariant::fillColor(bgLayer, backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1342 backgroundColor.b / 255.0f, this);
1343 bgLayer.alpha = backgroundColor.a / 255.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001344 layers.push_back(bgLayer);
Alec Mouribd17b3b2020-12-17 11:08:30 -08001345
1346 // add shadow layer
1347 renderengine::LayerSettings shadowLayer;
1348 shadowLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1349 shadowLayer.geometry.boundaries = castingBounds;
Derek Sollenbergerc31985e2021-05-18 16:38:17 -04001350 shadowLayer.skipContentDraw = true;
Alec Mouribd17b3b2020-12-17 11:08:30 -08001351 shadowLayer.alpha = 1.0f;
1352 ColorSourceVariant::fillColor(shadowLayer, 0, 0, 0, this);
1353 shadowLayer.shadow = shadow;
Sally Qi59a9f502021-10-12 18:53:23 +00001354 layers.push_back(shadowLayer);
Alec Mouribd17b3b2020-12-17 11:08:30 -08001355
Alec Mouric0aae732021-01-12 13:32:18 -08001356 invokeDraw(settings, layers);
Alec Mouribd17b3b2020-12-17 11:08:30 -08001357}
1358
Alec Mouri5a493722022-01-26 16:43:02 -08001359void RenderEngineTest::tonemap(ui::Dataspace sourceDataspace, std::function<vec3(vec3)> eotf,
1360 std::function<vec3(vec3, float)> scaleOotf) {
1361 constexpr int32_t kGreyLevels = 256;
1362
1363 const auto rect = Rect(0, 0, kGreyLevels, 1);
1364
1365 constexpr float kMaxLuminance = 750.f;
1366 constexpr float kCurrentLuminanceNits = 500.f;
1367 const renderengine::DisplaySettings display{
1368 .physicalDisplay = rect,
1369 .clip = rect,
1370 .maxLuminance = kMaxLuminance,
1371 .currentLuminanceNits = kCurrentLuminanceNits,
1372 .outputDataspace = ui::Dataspace::DISPLAY_P3,
1373 };
1374
1375 auto buf = std::make_shared<
1376 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07001377 ExternalTexture>(sp<GraphicBuffer>::make(kGreyLevels, 1,
1378 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1379 GRALLOC_USAGE_SW_READ_OFTEN |
1380 GRALLOC_USAGE_SW_WRITE_OFTEN |
1381 GRALLOC_USAGE_HW_RENDER |
1382 GRALLOC_USAGE_HW_TEXTURE,
1383 "input"),
Alec Mouri5a493722022-01-26 16:43:02 -08001384 *mRE,
1385 renderengine::impl::ExternalTexture::Usage::READABLE |
1386 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
1387 ASSERT_EQ(0, buf->getBuffer()->initCheck());
1388 {
1389 uint8_t* pixels;
1390 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1391 reinterpret_cast<void**>(&pixels));
1392
1393 uint8_t color = 0;
1394 for (int32_t j = 0; j < buf->getBuffer()->getHeight(); j++) {
1395 uint8_t* dest = pixels + (buf->getBuffer()->getStride() * j * 4);
1396 for (int32_t i = 0; i < buf->getBuffer()->getWidth(); i++) {
1397 dest[0] = color;
1398 dest[1] = color;
1399 dest[2] = color;
1400 dest[3] = 255;
1401 color++;
1402 dest += 4;
1403 }
1404 }
1405 buf->getBuffer()->unlock();
1406 }
1407
1408 mBuffer = std::make_shared<
1409 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07001410 ExternalTexture>(sp<GraphicBuffer>::make(kGreyLevels, 1,
1411 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1412 GRALLOC_USAGE_SW_READ_OFTEN |
1413 GRALLOC_USAGE_SW_WRITE_OFTEN |
1414 GRALLOC_USAGE_HW_RENDER |
1415 GRALLOC_USAGE_HW_TEXTURE,
1416 "output"),
Alec Mouri5a493722022-01-26 16:43:02 -08001417 *mRE,
1418 renderengine::impl::ExternalTexture::Usage::READABLE |
1419 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
1420 ASSERT_EQ(0, mBuffer->getBuffer()->initCheck());
1421
1422 const renderengine::LayerSettings layer{.geometry.boundaries = rect.toFloatRect(),
1423 .source =
1424 renderengine::PixelSource{
1425 .buffer =
1426 renderengine::Buffer{
1427 .buffer =
1428 std::move(buf),
1429 .usePremultipliedAlpha =
1430 true,
1431 },
1432 },
1433 .alpha = 1.0f,
1434 .sourceDataspace = sourceDataspace};
1435
1436 std::vector<renderengine::LayerSettings> layers{layer};
1437 invokeDraw(display, layers);
1438
1439 ColorSpace displayP3 = ColorSpace::DisplayP3();
1440 ColorSpace bt2020 = ColorSpace::BT2020();
1441
1442 tonemap::Metadata metadata{.displayMaxLuminance = 750.0f};
1443
1444 auto generator = [=](Point location) {
1445 const double normColor = static_cast<double>(location.x) / (kGreyLevels - 1);
1446 const vec3 rgb = vec3(normColor, normColor, normColor);
1447
1448 const vec3 linearRGB = eotf(rgb);
1449
1450 const vec3 xyz = bt2020.getRGBtoXYZ() * linearRGB;
1451
1452 const vec3 scaledXYZ = scaleOotf(xyz, kCurrentLuminanceNits);
Alec Mouri196b0f22022-03-04 22:13:48 +00001453 const auto gains =
Alec Mouri5a493722022-01-26 16:43:02 -08001454 tonemap::getToneMapper()
1455 ->lookupTonemapGain(static_cast<aidl::android::hardware::graphics::common::
1456 Dataspace>(sourceDataspace),
1457 static_cast<aidl::android::hardware::graphics::common::
1458 Dataspace>(
1459 ui::Dataspace::DISPLAY_P3),
Alec Mouri196b0f22022-03-04 22:13:48 +00001460 {tonemap::
1461 Color{.linearRGB =
1462 scaleOotf(linearRGB,
1463 kCurrentLuminanceNits),
1464 .xyz = scaledXYZ}},
Alec Mouri5a493722022-01-26 16:43:02 -08001465 metadata);
Alec Mouri196b0f22022-03-04 22:13:48 +00001466 EXPECT_EQ(1, gains.size());
1467 const double gain = gains.front();
Alec Mouri5a493722022-01-26 16:43:02 -08001468 const vec3 normalizedXYZ = scaledXYZ * gain / metadata.displayMaxLuminance;
1469
1470 const vec3 targetRGB = OETF_sRGB(displayP3.getXYZtoRGB() * normalizedXYZ) * 255;
1471 return ubyte4(static_cast<uint8_t>(targetRGB.r), static_cast<uint8_t>(targetRGB.g),
1472 static_cast<uint8_t>(targetRGB.b), 255);
1473 };
1474
1475 expectBufferColor(Rect(kGreyLevels, 1), generator, 2);
1476}
1477
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001478INSTANTIATE_TEST_SUITE_P(PerRenderEngineType, RenderEngineTest,
Alec Mouric16974e2022-09-13 17:35:48 +00001479 testing::Values(std::make_shared<SkiaGLESRenderEngineFactory>(),
Alec Mouri47bcb072023-08-15 02:02:49 +00001480 std::make_shared<SkiaVkRenderEngineFactory>()));
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001481
1482TEST_P(RenderEngineTest, drawLayers_noLayersToDraw) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001483 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001484 GTEST_SKIP();
1485 }
Alec Mouric0aae732021-01-12 13:32:18 -08001486 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001487 drawEmptyLayers();
1488}
1489
Sally Qi1fed86e2022-06-23 15:33:52 -07001490TEST_P(RenderEngineTest, drawLayers_fillRedBufferAndEmptyBuffer) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001491 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001492 GTEST_SKIP();
1493 }
Sally Qi1fed86e2022-06-23 15:33:52 -07001494 initializeRenderEngine();
1495 renderengine::DisplaySettings settings;
1496 settings.physicalDisplay = fullscreenRect();
1497 settings.clip = fullscreenRect();
1498 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1499
1500 // add a red layer
1501 renderengine::LayerSettings layerOne{
1502 .geometry.boundaries = fullscreenRect().toFloatRect(),
1503 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
1504 .alpha = 1.f,
1505 };
1506
1507 std::vector<renderengine::LayerSettings> layersFirst{layerOne};
1508 invokeDraw(settings, layersFirst);
1509 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
1510
1511 // re-draw with an empty layer above it, and we get a transparent black one
1512 std::vector<renderengine::LayerSettings> layersSecond;
1513 invokeDraw(settings, layersSecond);
1514 expectBufferColor(fullscreenRect(), 0, 0, 0, 0);
1515}
1516
Ana Krulec07b98df2021-01-07 14:38:40 -08001517TEST_P(RenderEngineTest, drawLayers_withoutBuffers_withColorTransform) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001518 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001519 GTEST_SKIP();
1520 }
Alec Mouria90a5702021-04-16 16:36:21 +00001521 initializeRenderEngine();
Ana Krulec07b98df2021-01-07 14:38:40 -08001522
1523 renderengine::DisplaySettings settings;
1524 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1525 settings.physicalDisplay = fullscreenRect();
1526 settings.clip = fullscreenRect();
1527
1528 // 255, 255, 255, 255 is full opaque white.
Alec Mouri4049b532021-10-15 20:59:33 -07001529 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
1530 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Ana Krulec07b98df2021-01-07 14:38:40 -08001531 // Create layer with given color.
1532 renderengine::LayerSettings bgLayer;
1533 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1534 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1535 bgLayer.source.solidColor = half3(backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1536 backgroundColor.b / 255.0f);
1537 bgLayer.alpha = backgroundColor.a / 255.0f;
1538 // Transform the red color.
1539 bgLayer.colorTransform = mat4(-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
1540
Sally Qi59a9f502021-10-12 18:53:23 +00001541 std::vector<renderengine::LayerSettings> layers;
1542 layers.push_back(bgLayer);
Ana Krulec07b98df2021-01-07 14:38:40 -08001543
Alec Mouric0aae732021-01-12 13:32:18 -08001544 invokeDraw(settings, layers);
Ana Krulec07b98df2021-01-07 14:38:40 -08001545
1546 // Expect to see full opaque pixel (with inverted red from the transform).
Alec Mouric0aae732021-01-12 13:32:18 -08001547 expectBufferColor(Rect(0, 0, 10, 10), 0.f, backgroundColor.g, backgroundColor.b,
Ana Krulec07b98df2021-01-07 14:38:40 -08001548 backgroundColor.a);
1549}
1550
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001551TEST_P(RenderEngineTest, drawLayers_nullOutputBuffer) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001552 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001553 GTEST_SKIP();
1554 }
Alec Mouric0aae732021-01-12 13:32:18 -08001555 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001556
Alec Mourid43ccab2019-03-13 12:23:45 -07001557 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001558 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Sally Qi59a9f502021-10-12 18:53:23 +00001559 std::vector<renderengine::LayerSettings> layers;
Alec Mourid43ccab2019-03-13 12:23:45 -07001560 renderengine::LayerSettings layer;
1561 layer.geometry.boundaries = fullscreenRect().toFloatRect();
1562 BufferSourceVariant<ForceOpaqueBufferVariant>::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
Sally Qi59a9f502021-10-12 18:53:23 +00001563 layers.push_back(layer);
Alec Mourif29700f2023-08-17 21:53:31 +00001564 ftl::Future<FenceResult> future = mRE->drawLayers(settings, layers, nullptr, base::unique_fd());
Alec Mourid43ccab2019-03-13 12:23:45 -07001565
Patrick Williams2e9748f2022-08-09 22:48:18 +00001566 ASSERT_TRUE(future.valid());
1567 auto result = future.get();
1568 ASSERT_FALSE(result.ok());
1569 ASSERT_EQ(BAD_VALUE, result.error());
Alec Mourid43ccab2019-03-13 12:23:45 -07001570}
1571
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001572TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001573 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001574 GTEST_SKIP();
1575 }
Alec Mouric0aae732021-01-12 13:32:18 -08001576 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001577 fillRedBuffer<ColorSourceVariant>();
1578}
1579
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001580TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001581 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001582 GTEST_SKIP();
1583 }
Alec Mouric0aae732021-01-12 13:32:18 -08001584 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001585 fillGreenBuffer<ColorSourceVariant>();
1586}
1587
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001588TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001589 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001590 GTEST_SKIP();
1591 }
Alec Mouric0aae732021-01-12 13:32:18 -08001592 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001593 fillBlueBuffer<ColorSourceVariant>();
1594}
1595
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001596TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001597 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001598 GTEST_SKIP();
1599 }
Alec Mouric0aae732021-01-12 13:32:18 -08001600 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001601 fillRedTransparentBuffer<ColorSourceVariant>();
1602}
1603
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001604TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001605 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001606 GTEST_SKIP();
1607 }
Alec Mouric0aae732021-01-12 13:32:18 -08001608 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001609 fillBufferPhysicalOffset<ColorSourceVariant>();
1610}
1611
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001612TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001613 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001614 GTEST_SKIP();
1615 }
Alec Mouric0aae732021-01-12 13:32:18 -08001616 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001617 fillBufferCheckersRotate0<ColorSourceVariant>();
1618}
1619
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001620TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001621 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001622 GTEST_SKIP();
1623 }
Alec Mouric0aae732021-01-12 13:32:18 -08001624 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001625 fillBufferCheckersRotate90<ColorSourceVariant>();
1626}
1627
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001628TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001629 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001630 GTEST_SKIP();
1631 }
Alec Mouric0aae732021-01-12 13:32:18 -08001632 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001633 fillBufferCheckersRotate180<ColorSourceVariant>();
1634}
1635
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001636TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001637 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001638 GTEST_SKIP();
1639 }
Alec Mouric0aae732021-01-12 13:32:18 -08001640 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001641 fillBufferCheckersRotate270<ColorSourceVariant>();
1642}
1643
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001644TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001645 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001646 GTEST_SKIP();
1647 }
Alec Mouric0aae732021-01-12 13:32:18 -08001648 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001649 fillBufferLayerTransform<ColorSourceVariant>();
1650}
1651
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001652TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001653 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001654 GTEST_SKIP();
1655 }
Alec Mouric0aae732021-01-12 13:32:18 -08001656 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08001657 fillBufferColorTransform<ColorSourceVariant>();
1658}
1659
Sally Qi2019fd22021-11-22 10:19:04 -08001660TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_sourceDataspace) {
1661 const auto& renderEngineFactory = GetParam();
1662 // skip for non color management
Leon Scroggins III696bf932024-01-24 15:21:05 -05001663 if (!renderEngineFactory->apiSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001664 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001665 }
1666
1667 initializeRenderEngine();
1668 fillBufferColorTransformAndSourceDataspace<ColorSourceVariant>();
1669}
1670
1671TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_outputDataspace) {
1672 const auto& renderEngineFactory = GetParam();
1673 // skip for non color management
Leon Scroggins III696bf932024-01-24 15:21:05 -05001674 if (!renderEngineFactory->apiSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001675 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001676 }
1677
1678 initializeRenderEngine();
1679 fillBufferColorTransformAndOutputDataspace<ColorSourceVariant>();
1680}
1681
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001682TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001683 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001684 GTEST_SKIP();
1685 }
Alec Mouric0aae732021-01-12 13:32:18 -08001686 initializeRenderEngine();
Alec Mouri7c94edb2018-12-03 21:23:26 -08001687 fillBufferWithRoundedCorners<ColorSourceVariant>();
1688}
1689
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001690TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001691 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001692 GTEST_SKIP();
1693 }
Alec Mouric0aae732021-01-12 13:32:18 -08001694 initializeRenderEngine();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001695 fillBufferColorTransformZeroLayerAlpha<ColorSourceVariant>();
1696}
1697
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001698TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001699 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001700 GTEST_SKIP();
1701 }
Alec Mouric0aae732021-01-12 13:32:18 -08001702 initializeRenderEngine();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001703 fillBufferAndBlurBackground<ColorSourceVariant>();
1704}
1705
Alec Mourie8489fd2021-04-29 16:08:56 -07001706TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001707 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001708 GTEST_SKIP();
1709 }
Alec Mourie8489fd2021-04-29 16:08:56 -07001710 initializeRenderEngine();
1711 fillSmallLayerAndBlurBackground<ColorSourceVariant>();
1712}
1713
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001714TEST_P(RenderEngineTest, drawLayers_overlayCorners_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001715 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001716 GTEST_SKIP();
1717 }
Alec Mouric0aae732021-01-12 13:32:18 -08001718 initializeRenderEngine();
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001719 overlayCorners<ColorSourceVariant>();
1720}
1721
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001722TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001723 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001724 GTEST_SKIP();
1725 }
Alec Mouric0aae732021-01-12 13:32:18 -08001726 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001727 fillRedBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1728}
1729
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001730TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001731 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001732 GTEST_SKIP();
1733 }
Alec Mouric0aae732021-01-12 13:32:18 -08001734 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001735 fillGreenBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1736}
1737
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001738TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001739 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001740 GTEST_SKIP();
1741 }
Alec Mouric0aae732021-01-12 13:32:18 -08001742 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001743 fillBlueBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1744}
1745
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001746TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001747 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001748 GTEST_SKIP();
1749 }
Alec Mouric0aae732021-01-12 13:32:18 -08001750 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001751 fillRedTransparentBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1752}
1753
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001754TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001755 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001756 GTEST_SKIP();
1757 }
Alec Mouric0aae732021-01-12 13:32:18 -08001758 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001759 fillBufferPhysicalOffset<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1760}
1761
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001762TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001763 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001764 GTEST_SKIP();
1765 }
Alec Mouric0aae732021-01-12 13:32:18 -08001766 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001767 fillBufferCheckersRotate0<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1768}
1769
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001770TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001771 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001772 GTEST_SKIP();
1773 }
Alec Mouric0aae732021-01-12 13:32:18 -08001774 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001775 fillBufferCheckersRotate90<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1776}
1777
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001778TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001779 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001780 GTEST_SKIP();
1781 }
Alec Mouric0aae732021-01-12 13:32:18 -08001782 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001783 fillBufferCheckersRotate180<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1784}
1785
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001786TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001787 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001788 GTEST_SKIP();
1789 }
Alec Mouric0aae732021-01-12 13:32:18 -08001790 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001791 fillBufferCheckersRotate270<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1792}
1793
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001794TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001795 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001796 GTEST_SKIP();
1797 }
Alec Mouric0aae732021-01-12 13:32:18 -08001798 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001799 fillBufferLayerTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1800}
1801
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001802TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001803 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001804 GTEST_SKIP();
1805 }
Alec Mouric0aae732021-01-12 13:32:18 -08001806 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08001807 fillBufferColorTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1808}
1809
Sally Qi2019fd22021-11-22 10:19:04 -08001810TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndSourceDataspace_opaqueBufferSource) {
1811 const auto& renderEngineFactory = GetParam();
1812 // skip for non color management
Leon Scroggins III696bf932024-01-24 15:21:05 -05001813 if (!renderEngineFactory->apiSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001814 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001815 }
1816
1817 initializeRenderEngine();
1818 fillBufferColorTransformAndSourceDataspace<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1819}
1820
1821TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndOutputDataspace_opaqueBufferSource) {
1822 const auto& renderEngineFactory = GetParam();
1823 // skip for non color management
Leon Scroggins III696bf932024-01-24 15:21:05 -05001824 if (!renderEngineFactory->apiSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001825 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001826 }
1827
1828 initializeRenderEngine();
1829 fillBufferColorTransformAndOutputDataspace<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1830}
1831
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001832TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001833 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001834 GTEST_SKIP();
1835 }
Alec Mouric0aae732021-01-12 13:32:18 -08001836 initializeRenderEngine();
Alec Mouri7c94edb2018-12-03 21:23:26 -08001837 fillBufferWithRoundedCorners<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1838}
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001839
Alec Mouric0aae732021-01-12 13:32:18 -08001840TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001841 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001842 GTEST_SKIP();
1843 }
Alec Mouric0aae732021-01-12 13:32:18 -08001844 initializeRenderEngine();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001845 fillBufferColorTransformZeroLayerAlpha<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1846}
Alec Mouri7c94edb2018-12-03 21:23:26 -08001847
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001848TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001849 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001850 GTEST_SKIP();
1851 }
Alec Mouric0aae732021-01-12 13:32:18 -08001852 initializeRenderEngine();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001853 fillBufferAndBlurBackground<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1854}
1855
Alec Mourie8489fd2021-04-29 16:08:56 -07001856TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001857 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001858 GTEST_SKIP();
1859 }
Alec Mourie8489fd2021-04-29 16:08:56 -07001860 initializeRenderEngine();
1861 fillSmallLayerAndBlurBackground<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1862}
1863
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001864TEST_P(RenderEngineTest, drawLayers_overlayCorners_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001865 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001866 GTEST_SKIP();
1867 }
Alec Mouric0aae732021-01-12 13:32:18 -08001868 initializeRenderEngine();
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001869 overlayCorners<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1870}
1871
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001872TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001873 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001874 GTEST_SKIP();
1875 }
Alec Mouric0aae732021-01-12 13:32:18 -08001876 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001877 fillRedBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1878}
1879
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001880TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001881 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001882 GTEST_SKIP();
1883 }
Alec Mouric0aae732021-01-12 13:32:18 -08001884 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001885 fillGreenBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1886}
1887
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001888TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001889 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001890 GTEST_SKIP();
1891 }
Alec Mouric0aae732021-01-12 13:32:18 -08001892 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001893 fillBlueBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1894}
1895
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001896TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001897 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001898 GTEST_SKIP();
1899 }
Alec Mouric0aae732021-01-12 13:32:18 -08001900 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001901 fillRedTransparentBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1902}
1903
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001904TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001905 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001906 GTEST_SKIP();
1907 }
Alec Mouric0aae732021-01-12 13:32:18 -08001908 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001909 fillBufferPhysicalOffset<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1910}
1911
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001912TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001913 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001914 GTEST_SKIP();
1915 }
Alec Mouric0aae732021-01-12 13:32:18 -08001916 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001917 fillBufferCheckersRotate0<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1918}
1919
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001920TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001921 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001922 GTEST_SKIP();
1923 }
Alec Mouric0aae732021-01-12 13:32:18 -08001924 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001925 fillBufferCheckersRotate90<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1926}
1927
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001928TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001929 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001930 GTEST_SKIP();
1931 }
Alec Mouric0aae732021-01-12 13:32:18 -08001932 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001933 fillBufferCheckersRotate180<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1934}
1935
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001936TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001937 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001938 GTEST_SKIP();
1939 }
Alec Mouric0aae732021-01-12 13:32:18 -08001940 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001941 fillBufferCheckersRotate270<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1942}
1943
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001944TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001945 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001946 GTEST_SKIP();
1947 }
Alec Mouric0aae732021-01-12 13:32:18 -08001948 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001949 fillBufferLayerTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1950}
1951
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001952TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001953 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001954 GTEST_SKIP();
1955 }
Alec Mouric0aae732021-01-12 13:32:18 -08001956 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08001957 fillBufferColorTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1958}
1959
Sally Qi2019fd22021-11-22 10:19:04 -08001960TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndSourceDataspace_bufferSource) {
1961 const auto& renderEngineFactory = GetParam();
1962 // skip for non color management
Leon Scroggins III696bf932024-01-24 15:21:05 -05001963 if (!renderEngineFactory->apiSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001964 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001965 }
1966
1967 initializeRenderEngine();
1968 fillBufferColorTransformAndSourceDataspace<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1969}
1970
1971TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndOutputDataspace_bufferSource) {
1972 const auto& renderEngineFactory = GetParam();
1973 // skip for non color management
Leon Scroggins III696bf932024-01-24 15:21:05 -05001974 if (!renderEngineFactory->apiSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001975 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001976 }
1977
1978 initializeRenderEngine();
1979 fillBufferColorTransformAndOutputDataspace<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1980}
1981
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001982TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001983 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001984 GTEST_SKIP();
1985 }
Alec Mouric0aae732021-01-12 13:32:18 -08001986 initializeRenderEngine();
Alec Mouri7c94edb2018-12-03 21:23:26 -08001987 fillBufferWithRoundedCorners<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1988}
1989
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001990TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001991 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001992 GTEST_SKIP();
1993 }
Alec Mouric0aae732021-01-12 13:32:18 -08001994 initializeRenderEngine();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001995 fillBufferColorTransformZeroLayerAlpha<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1996}
1997
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001998TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001999 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002000 GTEST_SKIP();
2001 }
Alec Mouric0aae732021-01-12 13:32:18 -08002002 initializeRenderEngine();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08002003 fillBufferAndBlurBackground<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2004}
2005
Alec Mourie8489fd2021-04-29 16:08:56 -07002006TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002007 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002008 GTEST_SKIP();
2009 }
Alec Mourie8489fd2021-04-29 16:08:56 -07002010 initializeRenderEngine();
2011 fillSmallLayerAndBlurBackground<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2012}
2013
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002014TEST_P(RenderEngineTest, drawLayers_overlayCorners_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002015 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002016 GTEST_SKIP();
2017 }
Alec Mouric0aae732021-01-12 13:32:18 -08002018 initializeRenderEngine();
Alec Mourie7d1d4a2019-02-05 01:13:46 +00002019 overlayCorners<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2020}
2021
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002022TEST_P(RenderEngineTest, drawLayers_fillBufferTextureTransform) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002023 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002024 GTEST_SKIP();
2025 }
Alec Mouric0aae732021-01-12 13:32:18 -08002026 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002027 fillBufferTextureTransform();
2028}
2029
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002030TEST_P(RenderEngineTest, drawLayers_fillBuffer_premultipliesAlpha) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002031 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002032 GTEST_SKIP();
2033 }
Alec Mouric0aae732021-01-12 13:32:18 -08002034 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002035 fillBufferWithPremultiplyAlpha();
2036}
2037
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002038TEST_P(RenderEngineTest, drawLayers_fillBuffer_withoutPremultiplyingAlpha) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002039 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002040 GTEST_SKIP();
2041 }
Alec Mouric0aae732021-01-12 13:32:18 -08002042 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002043 fillBufferWithoutPremultiplyAlpha();
2044}
2045
Alec Mouribd17b3b2020-12-17 11:08:30 -08002046TEST_P(RenderEngineTest, drawLayers_fillShadow_castsWithoutCasterLayer) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002047 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002048 GTEST_SKIP();
2049 }
Alec Mouric0aae732021-01-12 13:32:18 -08002050 initializeRenderEngine();
Alec Mouribd17b3b2020-12-17 11:08:30 -08002051
Alec Mouri4049b532021-10-15 20:59:33 -07002052 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2053 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Alec Mouribd17b3b2020-12-17 11:08:30 -08002054 const float shadowLength = 5.0f;
2055 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2056 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
Vishnu Naird9e4f462023-10-06 04:05:45 +00002057 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2058 shadowLength, false /* casterIsTranslucent */);
Alec Mouribd17b3b2020-12-17 11:08:30 -08002059
2060 drawShadowWithoutCaster(casterBounds.toFloatRect(), settings, backgroundColor);
2061 expectShadowColorWithoutCaster(casterBounds.toFloatRect(), settings, backgroundColor);
2062}
2063
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002064TEST_P(RenderEngineTest, drawLayers_fillShadow_casterLayerMinSize) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002065 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002066 GTEST_SKIP();
2067 }
Alec Mouric0aae732021-01-12 13:32:18 -08002068 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002069
Alec Mouri4049b532021-10-15 20:59:33 -07002070 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2071 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2072 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2073 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002074 const float shadowLength = 5.0f;
2075 Rect casterBounds(1, 1);
2076 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2077 renderengine::LayerSettings castingLayer;
2078 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2079 castingLayer.alpha = 1.0f;
Vishnu Naird9e4f462023-10-06 04:05:45 +00002080 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2081 shadowLength, false /* casterIsTranslucent */);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002082
2083 drawShadow<ColorSourceVariant>(castingLayer, settings, casterColor, backgroundColor);
2084 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2085}
2086
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002087TEST_P(RenderEngineTest, drawLayers_fillShadow_casterColorLayer) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002088 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002089 GTEST_SKIP();
2090 }
Alec Mouric0aae732021-01-12 13:32:18 -08002091 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002092
Alec Mouri4049b532021-10-15 20:59:33 -07002093 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2094 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2095 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2096 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002097 const float shadowLength = 5.0f;
2098 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2099 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2100 renderengine::LayerSettings castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002101 castingLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002102 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2103 castingLayer.alpha = 1.0f;
Vishnu Naird9e4f462023-10-06 04:05:45 +00002104 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2105 shadowLength, false /* casterIsTranslucent */);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002106
2107 drawShadow<ColorSourceVariant>(castingLayer, settings, casterColor, backgroundColor);
2108 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2109}
2110
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002111TEST_P(RenderEngineTest, drawLayers_fillShadow_casterOpaqueBufferLayer) {
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();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002116
Alec Mouri4049b532021-10-15 20:59:33 -07002117 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2118 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2119 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2120 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002121 const float shadowLength = 5.0f;
2122 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2123 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2124 renderengine::LayerSettings castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002125 castingLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002126 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2127 castingLayer.alpha = 1.0f;
Vishnu Naird9e4f462023-10-06 04:05:45 +00002128 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2129 shadowLength, false /* casterIsTranslucent */);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002130
2131 drawShadow<BufferSourceVariant<ForceOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2132 backgroundColor);
2133 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2134}
2135
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002136TEST_P(RenderEngineTest, drawLayers_fillShadow_casterWithRoundedCorner) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002137 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002138 GTEST_SKIP();
2139 }
Alec Mouric0aae732021-01-12 13:32:18 -08002140 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002141
Alec Mouri4049b532021-10-15 20:59:33 -07002142 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2143 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2144 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2145 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002146 const float shadowLength = 5.0f;
2147 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2148 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2149 renderengine::LayerSettings castingLayer;
2150 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002151 castingLayer.geometry.roundedCornersRadius = {3.0f, 3.0f};
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002152 castingLayer.geometry.roundedCornersCrop = casterBounds.toFloatRect();
2153 castingLayer.alpha = 1.0f;
Vishnu Naird9e4f462023-10-06 04:05:45 +00002154 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2155 shadowLength, false /* casterIsTranslucent */);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002156
2157 drawShadow<BufferSourceVariant<ForceOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2158 backgroundColor);
2159 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2160}
2161
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002162TEST_P(RenderEngineTest, drawLayers_fillShadow_translucentCasterWithAlpha) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002163 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002164 GTEST_SKIP();
2165 }
Alec Mouric0aae732021-01-12 13:32:18 -08002166 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002167
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002168 const ubyte4 casterColor(255, 0, 0, 255);
2169 const ubyte4 backgroundColor(255, 255, 255, 255);
2170 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;
2174 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2175 castingLayer.alpha = 0.5f;
Vishnu Naird9e4f462023-10-06 04:05:45 +00002176 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2177 shadowLength, true /* casterIsTranslucent */);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002178
2179 drawShadow<BufferSourceVariant<RelaxOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2180 backgroundColor);
2181
2182 // verify only the background since the shadow will draw behind the caster
2183 const float shadowInset = settings.length * -1.0f;
2184 const Rect casterWithShadow =
2185 Rect(casterBounds).inset(shadowInset, shadowInset, shadowInset, shadowInset);
2186 const Region backgroundRegion = Region(fullscreenRect()).subtractSelf(casterWithShadow);
2187 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
2188 backgroundColor.a);
2189}
2190
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002191TEST_P(RenderEngineTest, cleanupPostRender_cleansUpOnce) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002192 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002193 GTEST_SKIP();
2194 }
Alec Mouric0aae732021-01-12 13:32:18 -08002195 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002196
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002197 renderengine::DisplaySettings settings;
2198 settings.physicalDisplay = fullscreenRect();
2199 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002200 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002201
Sally Qi59a9f502021-10-12 18:53:23 +00002202 std::vector<renderengine::LayerSettings> layers;
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002203 renderengine::LayerSettings layer;
2204 layer.geometry.boundaries = fullscreenRect().toFloatRect();
2205 BufferSourceVariant<ForceOpaqueBufferVariant>::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
2206 layer.alpha = 1.0;
Sally Qi59a9f502021-10-12 18:53:23 +00002207 layers.push_back(layer);
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002208
Patrick Williams2e9748f2022-08-09 22:48:18 +00002209 ftl::Future<FenceResult> futureOne =
Alec Mourif29700f2023-08-17 21:53:31 +00002210 mRE->drawLayers(settings, layers, mBuffer, base::unique_fd());
Patrick Williams2e9748f2022-08-09 22:48:18 +00002211 ASSERT_TRUE(futureOne.valid());
2212 auto resultOne = futureOne.get();
2213 ASSERT_TRUE(resultOne.ok());
2214 auto fenceOne = resultOne.value();
Sally Qi4cabdd02021-08-05 16:45:57 -07002215
Patrick Williams2e9748f2022-08-09 22:48:18 +00002216 ftl::Future<FenceResult> futureTwo =
Alec Mourif29700f2023-08-17 21:53:31 +00002217 mRE->drawLayers(settings, layers, mBuffer, base::unique_fd(fenceOne->dup()));
Patrick Williams2e9748f2022-08-09 22:48:18 +00002218 ASSERT_TRUE(futureTwo.valid());
2219 auto resultTwo = futureTwo.get();
2220 ASSERT_TRUE(resultTwo.ok());
2221 auto fenceTwo = resultTwo.value();
2222 fenceTwo->waitForever(LOG_TAG);
Derek Sollenbergerec411212021-08-25 10:54:47 -04002223
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002224 // Only cleanup the first time.
Ian Elliott1f0911e2022-09-09 16:31:47 -06002225 if (mRE->canSkipPostRenderCleanup()) {
2226 // Skia's Vk backend may keep the texture alive beyond drawLayersInternal, so
2227 // it never gets added to the cleanup list. In those cases, we can skip.
Leon Scroggins III696bf932024-01-24 15:21:05 -05002228 EXPECT_TRUE(GetParam()->graphicsApi() == renderengine::RenderEngine::GraphicsApi::VK);
Ian Elliott1f0911e2022-09-09 16:31:47 -06002229 } else {
2230 mRE->cleanupPostRender();
2231 EXPECT_TRUE(mRE->canSkipPostRenderCleanup());
2232 }
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002233}
2234
Ana Krulecf9a15d92020-12-11 08:35:00 -08002235TEST_P(RenderEngineTest, testRoundedCornersCrop) {
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 Krulecf9a15d92020-12-11 08:35:00 -08002240
2241 renderengine::DisplaySettings settings;
2242 settings.physicalDisplay = fullscreenRect();
2243 settings.clip = fullscreenRect();
2244 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2245
Sally Qi59a9f502021-10-12 18:53:23 +00002246 std::vector<renderengine::LayerSettings> layers;
Ana Krulecf9a15d92020-12-11 08:35:00 -08002247
2248 renderengine::LayerSettings redLayer;
2249 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2250 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002251 redLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
2252
Ana Krulecf9a15d92020-12-11 08:35:00 -08002253 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2254 // Red background.
2255 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2256 redLayer.alpha = 1.0f;
2257
Sally Qi59a9f502021-10-12 18:53:23 +00002258 layers.push_back(redLayer);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002259
2260 // Green layer with 1/3 size.
2261 renderengine::LayerSettings greenLayer;
2262 greenLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2263 greenLayer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002264 greenLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
Ana Krulecf9a15d92020-12-11 08:35:00 -08002265 // Bottom right corner is not going to be rounded.
2266 greenLayer.geometry.roundedCornersCrop =
2267 Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3, DEFAULT_DISPLAY_HEIGHT,
2268 DEFAULT_DISPLAY_HEIGHT)
2269 .toFloatRect();
2270 greenLayer.source.solidColor = half3(0.0f, 1.0f, 0.0f);
2271 greenLayer.alpha = 1.0f;
2272
Sally Qi59a9f502021-10-12 18:53:23 +00002273 layers.push_back(greenLayer);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002274
Alec Mouric0aae732021-01-12 13:32:18 -08002275 invokeDraw(settings, layers);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002276
2277 // Corners should be ignored...
2278 // Screen size: width is 128, height is 256.
2279 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 0);
2280 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, 0, DEFAULT_DISPLAY_WIDTH, 1), 0, 0, 0, 0);
2281 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT - 1, 1, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
2282 // Bottom right corner is kept out of the clipping, and it's green.
2283 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1,
2284 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
2285 0, 255, 0, 255);
2286}
2287
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002288TEST_P(RenderEngineTest, testRoundedCornersParentCrop) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002289 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002290 GTEST_SKIP();
2291 }
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002292 initializeRenderEngine();
2293
2294 renderengine::DisplaySettings settings;
2295 settings.physicalDisplay = fullscreenRect();
2296 settings.clip = fullscreenRect();
2297 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2298
Sally Qi59a9f502021-10-12 18:53:23 +00002299 std::vector<renderengine::LayerSettings> layers;
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002300
2301 renderengine::LayerSettings redLayer;
2302 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2303 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002304 redLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002305 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2306 // Red background.
2307 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2308 redLayer.alpha = 1.0f;
2309
Sally Qi59a9f502021-10-12 18:53:23 +00002310 layers.push_back(redLayer);
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002311
2312 // Green layer with 1/2 size with parent crop rect.
2313 renderengine::LayerSettings greenLayer = redLayer;
2314 greenLayer.geometry.boundaries =
2315 FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT / 2);
2316 greenLayer.source.solidColor = half3(0.0f, 1.0f, 0.0f);
2317
Sally Qi59a9f502021-10-12 18:53:23 +00002318 layers.push_back(greenLayer);
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002319
2320 invokeDraw(settings, layers);
2321
2322 // Due to roundedCornersRadius, the corners are untouched.
2323 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2324 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2325 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2326 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2327
2328 // top middle should be green and the bottom middle red
2329 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, 0), 0, 255, 0, 255);
2330 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0, 255);
2331
2332 // the bottom edge of the green layer should not be rounded
2333 expectBufferColor(Point(0, (DEFAULT_DISPLAY_HEIGHT / 2) - 1), 0, 255, 0, 255);
2334}
2335
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002336TEST_P(RenderEngineTest, testRoundedCornersParentCropSmallBounds) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002337 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002338 GTEST_SKIP();
2339 }
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002340 initializeRenderEngine();
2341
2342 renderengine::DisplaySettings settings;
2343 settings.physicalDisplay = fullscreenRect();
2344 settings.clip = fullscreenRect();
2345 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2346
Sally Qi59a9f502021-10-12 18:53:23 +00002347 std::vector<renderengine::LayerSettings> layers;
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002348
2349 renderengine::LayerSettings redLayer;
2350 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2351 redLayer.geometry.boundaries = FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, 32);
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002352 redLayer.geometry.roundedCornersRadius = {64.0f, 64.0f};
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002353 redLayer.geometry.roundedCornersCrop = FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, 128);
2354 // Red background.
2355 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2356 redLayer.alpha = 1.0f;
2357
Sally Qi59a9f502021-10-12 18:53:23 +00002358 layers.push_back(redLayer);
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002359 invokeDraw(settings, layers);
2360
2361 // Due to roundedCornersRadius, the top corners are untouched.
2362 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2363 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2364
2365 // ensure that the entire height of the red layer was clipped by the rounded corners crop.
2366 expectBufferColor(Point(0, 31), 0, 0, 0, 0);
2367 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 31), 0, 0, 0, 0);
2368
2369 // the bottom middle should be red
2370 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, 31), 255, 0, 0, 255);
2371}
2372
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002373TEST_P(RenderEngineTest, testRoundedCornersXY) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002374 if (GetParam()->graphicsApi() != renderengine::RenderEngine::GraphicsApi::GL) {
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002375 GTEST_SKIP();
2376 }
2377
2378 initializeRenderEngine();
2379
2380 renderengine::DisplaySettings settings;
2381 settings.physicalDisplay = fullscreenRect();
2382 settings.clip = fullscreenRect();
2383 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2384
2385 std::vector<renderengine::LayerSettings> layers;
2386
2387 renderengine::LayerSettings redLayer;
2388 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2389 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
2390 redLayer.geometry.roundedCornersRadius = {5.0f, 20.0f};
2391 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2392 // Red background.
2393 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2394 redLayer.alpha = 1.0f;
2395
2396 layers.push_back(redLayer);
2397
2398 invokeDraw(settings, layers);
2399
2400 // Due to roundedCornersRadius, the corners are untouched.
2401 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2402 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2403 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2404 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2405
2406 // Y-axis draws a larger radius, check that its untouched as well
2407 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 5), 0, 0, 0, 0);
2408 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 5), 0, 0, 0, 0);
2409 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 5), 0, 0, 0, 0);
2410 expectBufferColor(Point(0, 5), 0, 0, 0, 0);
2411
2412 // middle should be red
2413 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0, 255);
2414}
2415
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002416TEST_P(RenderEngineTest, testClear) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002417 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002418 GTEST_SKIP();
2419 }
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002420 initializeRenderEngine();
2421
2422 const auto rect = fullscreenRect();
2423 const renderengine::DisplaySettings display{
2424 .physicalDisplay = rect,
2425 .clip = rect,
2426 };
2427
2428 const renderengine::LayerSettings redLayer{
2429 .geometry.boundaries = rect.toFloatRect(),
2430 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
2431 .alpha = 1.0f,
2432 };
2433
2434 // This mimics prepareClearClientComposition. This layer should overwrite
2435 // the redLayer, so that the buffer is transparent, rather than red.
2436 const renderengine::LayerSettings clearLayer{
2437 .geometry.boundaries = rect.toFloatRect(),
2438 .source.solidColor = half3(0.0f, 0.0f, 0.0f),
2439 .alpha = 0.0f,
2440 .disableBlending = true,
2441 };
2442
Sally Qi59a9f502021-10-12 18:53:23 +00002443 std::vector<renderengine::LayerSettings> layers{redLayer, clearLayer};
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002444 invokeDraw(display, layers);
2445 expectBufferColor(rect, 0, 0, 0, 0);
2446}
2447
2448TEST_P(RenderEngineTest, testDisableBlendingBuffer) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002449 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002450 GTEST_SKIP();
2451 }
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002452 initializeRenderEngine();
2453
2454 const auto rect = Rect(0, 0, 1, 1);
2455 const renderengine::DisplaySettings display{
2456 .physicalDisplay = rect,
2457 .clip = rect,
2458 };
2459
2460 const renderengine::LayerSettings redLayer{
2461 .geometry.boundaries = rect.toFloatRect(),
2462 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
2463 .alpha = 1.0f,
2464 };
2465
2466 // The next layer will overwrite redLayer with a GraphicBuffer that is green
2467 // applied with a translucent alpha.
Alec Mouria90a5702021-04-16 16:36:21 +00002468 const auto buf = allocateSourceBuffer(1, 1);
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002469 {
2470 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00002471 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2472 reinterpret_cast<void**>(&pixels));
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002473 pixels[0] = 0;
2474 pixels[1] = 255;
2475 pixels[2] = 0;
2476 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00002477 buf->getBuffer()->unlock();
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002478 }
2479
2480 const renderengine::LayerSettings greenLayer{
2481 .geometry.boundaries = rect.toFloatRect(),
2482 .source =
2483 renderengine::PixelSource{
2484 .buffer =
2485 renderengine::Buffer{
2486 .buffer = buf,
2487 .usePremultipliedAlpha = true,
2488 },
2489 },
2490 .alpha = 0.5f,
2491 .disableBlending = true,
2492 };
2493
Sally Qi59a9f502021-10-12 18:53:23 +00002494 std::vector<renderengine::LayerSettings> layers{redLayer, greenLayer};
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002495 invokeDraw(display, layers);
2496 expectBufferColor(rect, 0, 128, 0, 128);
2497}
2498
Tianhao Yao67dd7122022-02-22 17:48:33 +00002499TEST_P(RenderEngineTest, testBorder) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002500 if (GetParam()->graphicsApi() != renderengine::RenderEngine::GraphicsApi::GL) {
Tianhao Yao67dd7122022-02-22 17:48:33 +00002501 GTEST_SKIP();
2502 }
2503
Tianhao Yao67dd7122022-02-22 17:48:33 +00002504 initializeRenderEngine();
2505
2506 const ui::Dataspace dataspace = ui::Dataspace::V0_SRGB;
2507
2508 const auto displayRect = Rect(1080, 2280);
2509 renderengine::DisplaySettings display{
2510 .physicalDisplay = displayRect,
2511 .clip = displayRect,
2512 .outputDataspace = dataspace,
2513 };
2514 display.borderInfoList.clear();
2515 renderengine::BorderRenderInfo info;
2516 info.combinedRegion = Region(Rect(99, 99, 199, 199));
Tianhao Yao10cea3c2022-03-30 01:37:22 +00002517 info.width = 20.0f;
2518 info.color = half4{1.0f, 128.0f / 255.0f, 0.0f, 1.0f};
Tianhao Yao67dd7122022-02-22 17:48:33 +00002519 display.borderInfoList.emplace_back(info);
2520
2521 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2522 const renderengine::LayerSettings greenLayer{
2523 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2524 .source =
2525 renderengine::PixelSource{
2526 .buffer =
2527 renderengine::Buffer{
2528 .buffer = greenBuffer,
2529 .usePremultipliedAlpha = true,
2530 },
2531 },
2532 .alpha = 1.0f,
2533 .sourceDataspace = dataspace,
2534 .whitePointNits = 200.f,
2535 };
2536
2537 std::vector<renderengine::LayerSettings> layers;
2538 layers.emplace_back(greenLayer);
2539 invokeDraw(display, layers);
2540
2541 expectBufferColor(Rect(99, 99, 101, 101), 255, 128, 0, 255, 1);
2542}
2543
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002544TEST_P(RenderEngineTest, testDimming) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002545 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002546 GTEST_SKIP();
2547 }
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002548 initializeRenderEngine();
2549
Alec Mouri85065692022-03-18 00:58:26 +00002550 const ui::Dataspace dataspace = ui::Dataspace::V0_SRGB_LINEAR;
2551
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002552 const auto displayRect = Rect(3, 1);
2553 const renderengine::DisplaySettings display{
2554 .physicalDisplay = displayRect,
2555 .clip = displayRect,
Alec Mouri85065692022-03-18 00:58:26 +00002556 .outputDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002557 .targetLuminanceNits = 1000.f,
2558 };
2559
2560 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2561 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2562 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2563
2564 const renderengine::LayerSettings greenLayer{
2565 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2566 .source =
2567 renderengine::PixelSource{
2568 .buffer =
2569 renderengine::Buffer{
2570 .buffer = greenBuffer,
2571 .usePremultipliedAlpha = true,
2572 },
2573 },
2574 .alpha = 1.0f,
Alec Mouri85065692022-03-18 00:58:26 +00002575 .sourceDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002576 .whitePointNits = 200.f,
2577 };
2578
2579 const renderengine::LayerSettings blueLayer{
2580 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2581 .source =
2582 renderengine::PixelSource{
2583 .buffer =
2584 renderengine::Buffer{
2585 .buffer = blueBuffer,
2586 .usePremultipliedAlpha = true,
2587 },
2588 },
2589 .alpha = 1.0f,
Alec Mouri85065692022-03-18 00:58:26 +00002590 .sourceDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002591 .whitePointNits = 1000.f / 51.f,
2592 };
2593
2594 const renderengine::LayerSettings redLayer{
2595 .geometry.boundaries = FloatRect(2.f, 0.f, 3.f, 1.f),
2596 .source =
2597 renderengine::PixelSource{
2598 .buffer =
2599 renderengine::Buffer{
2600 .buffer = redBuffer,
2601 .usePremultipliedAlpha = true,
2602 },
2603 },
2604 .alpha = 1.0f,
Alec Mouri85065692022-03-18 00:58:26 +00002605 .sourceDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002606 // When the white point is not set for a layer, just ignore it and treat it as the same
2607 // as the max layer
2608 .whitePointNits = -1.f,
2609 };
2610
2611 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer, redLayer};
2612 invokeDraw(display, layers);
2613
2614 expectBufferColor(Rect(1, 1), 0, 51, 0, 255, 1);
2615 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 5, 255, 1);
2616 expectBufferColor(Rect(2, 0, 3, 1), 51, 0, 0, 255, 1);
2617}
2618
Alec Mouri85065692022-03-18 00:58:26 +00002619TEST_P(RenderEngineTest, testDimming_inGammaSpace) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002620 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002621 GTEST_SKIP();
2622 }
Alec Mouri85065692022-03-18 00:58:26 +00002623 initializeRenderEngine();
2624
2625 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2626 ui::Dataspace::TRANSFER_GAMMA2_2 |
2627 ui::Dataspace::RANGE_FULL);
2628
2629 const auto displayRect = Rect(3, 1);
2630 const renderengine::DisplaySettings display{
2631 .physicalDisplay = displayRect,
2632 .clip = displayRect,
2633 .outputDataspace = dataspace,
2634 .targetLuminanceNits = 1000.f,
2635 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2636 };
2637
2638 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2639 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2640 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2641
2642 const renderengine::LayerSettings greenLayer{
2643 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2644 .source =
2645 renderengine::PixelSource{
2646 .buffer =
2647 renderengine::Buffer{
2648 .buffer = greenBuffer,
2649 .usePremultipliedAlpha = true,
2650 },
2651 },
2652 .alpha = 1.0f,
2653 .sourceDataspace = dataspace,
2654 .whitePointNits = 200.f,
2655 };
2656
2657 const renderengine::LayerSettings blueLayer{
2658 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2659 .source =
2660 renderengine::PixelSource{
2661 .buffer =
2662 renderengine::Buffer{
2663 .buffer = blueBuffer,
2664 .usePremultipliedAlpha = true,
2665 },
2666 },
2667 .alpha = 1.0f,
2668 .sourceDataspace = dataspace,
2669 .whitePointNits = 1000.f / 51.f,
2670 };
2671
2672 const renderengine::LayerSettings redLayer{
2673 .geometry.boundaries = FloatRect(2.f, 0.f, 3.f, 1.f),
2674 .source =
2675 renderengine::PixelSource{
2676 .buffer =
2677 renderengine::Buffer{
2678 .buffer = redBuffer,
2679 .usePremultipliedAlpha = true,
2680 },
2681 },
2682 .alpha = 1.0f,
2683 .sourceDataspace = dataspace,
2684 // When the white point is not set for a layer, just ignore it and treat it as the same
2685 // as the max layer
2686 .whitePointNits = -1.f,
2687 };
2688
2689 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer, redLayer};
2690 invokeDraw(display, layers);
2691
2692 expectBufferColor(Rect(1, 1), 0, 122, 0, 255, 1);
2693 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 42, 255, 1);
2694 expectBufferColor(Rect(2, 0, 3, 1), 122, 0, 0, 255, 1);
2695}
2696
Alec Mouri9bcd1d12022-04-21 22:16:56 +00002697TEST_P(RenderEngineTest, testDimming_inGammaSpace_withDisplayColorTransform) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002698 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002699 GTEST_SKIP();
2700 }
Alec Mouri9bcd1d12022-04-21 22:16:56 +00002701 initializeRenderEngine();
2702
2703 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2704 ui::Dataspace::TRANSFER_GAMMA2_2 |
2705 ui::Dataspace::RANGE_FULL);
2706
2707 const auto displayRect = Rect(3, 1);
2708 const renderengine::DisplaySettings display{
2709 .physicalDisplay = displayRect,
2710 .clip = displayRect,
2711 .outputDataspace = dataspace,
2712 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
2713 .targetLuminanceNits = 1000.f,
2714 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2715 };
2716
2717 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2718 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2719 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2720
2721 const renderengine::LayerSettings greenLayer{
2722 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2723 .source =
2724 renderengine::PixelSource{
2725 .buffer =
2726 renderengine::Buffer{
2727 .buffer = greenBuffer,
2728 .usePremultipliedAlpha = true,
2729 },
2730 },
2731 .alpha = 1.0f,
2732 .sourceDataspace = dataspace,
2733 .whitePointNits = 200.f,
2734 };
2735
2736 const renderengine::LayerSettings redLayer{
2737 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2738 .source =
2739 renderengine::PixelSource{
2740 .buffer =
2741 renderengine::Buffer{
2742 .buffer = redBuffer,
2743 .usePremultipliedAlpha = true,
2744 },
2745 },
2746 .alpha = 1.0f,
2747 .sourceDataspace = dataspace,
2748 // When the white point is not set for a layer, just ignore it and treat it as the same
2749 // as the max layer
2750 .whitePointNits = -1.f,
2751 };
2752
2753 std::vector<renderengine::LayerSettings> layers{greenLayer, redLayer};
2754 invokeDraw(display, layers);
2755
2756 expectBufferColor(Rect(1, 1), 0, 0, 0, 255, 1);
2757 expectBufferColor(Rect(1, 0, 2, 1), 0, 122, 0, 255, 1);
2758}
2759
2760TEST_P(RenderEngineTest, testDimming_inGammaSpace_withDisplayColorTransform_deviceHandles) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002761 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002762 GTEST_SKIP();
2763 }
Alec Mouri9bcd1d12022-04-21 22:16:56 +00002764 initializeRenderEngine();
2765
2766 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2767 ui::Dataspace::TRANSFER_GAMMA2_2 |
2768 ui::Dataspace::RANGE_FULL);
2769
2770 const auto displayRect = Rect(3, 1);
2771 const renderengine::DisplaySettings display{
2772 .physicalDisplay = displayRect,
2773 .clip = displayRect,
2774 .outputDataspace = dataspace,
2775 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
2776 .deviceHandlesColorTransform = true,
2777 .targetLuminanceNits = 1000.f,
2778 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2779 };
2780
2781 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2782 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2783 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2784
2785 const renderengine::LayerSettings greenLayer{
2786 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2787 .source =
2788 renderengine::PixelSource{
2789 .buffer =
2790 renderengine::Buffer{
2791 .buffer = greenBuffer,
2792 .usePremultipliedAlpha = true,
2793 },
2794 },
2795 .alpha = 1.0f,
2796 .sourceDataspace = dataspace,
2797 .whitePointNits = 200.f,
2798 };
2799
2800 const renderengine::LayerSettings redLayer{
2801 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2802 .source =
2803 renderengine::PixelSource{
2804 .buffer =
2805 renderengine::Buffer{
2806 .buffer = redBuffer,
2807 .usePremultipliedAlpha = true,
2808 },
2809 },
2810 .alpha = 1.0f,
2811 .sourceDataspace = dataspace,
2812 // When the white point is not set for a layer, just ignore it and treat it as the same
2813 // as the max layer
2814 .whitePointNits = -1.f,
2815 };
2816
2817 std::vector<renderengine::LayerSettings> layers{greenLayer, redLayer};
2818 invokeDraw(display, layers);
2819
2820 expectBufferColor(Rect(1, 1), 0, 122, 0, 255, 1);
2821 expectBufferColor(Rect(1, 0, 2, 1), 122, 0, 0, 255, 1);
2822}
2823
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002824TEST_P(RenderEngineTest, testDimming_withoutTargetLuminance) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002825 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002826 GTEST_SKIP();
2827 }
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002828 initializeRenderEngine();
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002829
2830 const auto displayRect = Rect(2, 1);
2831 const renderengine::DisplaySettings display{
2832 .physicalDisplay = displayRect,
2833 .clip = displayRect,
2834 .outputDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2835 .targetLuminanceNits = -1.f,
2836 };
2837
2838 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2839 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2840
2841 const renderengine::LayerSettings greenLayer{
2842 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2843 .source =
2844 renderengine::PixelSource{
2845 .buffer =
2846 renderengine::Buffer{
2847 .buffer = greenBuffer,
2848 .usePremultipliedAlpha = true,
2849 },
2850 },
2851 .alpha = 1.0f,
2852 .sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2853 .whitePointNits = 200.f,
2854 };
2855
2856 const renderengine::LayerSettings blueLayer{
2857 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2858 .source =
2859 renderengine::PixelSource{
2860 .buffer =
2861 renderengine::Buffer{
2862 .buffer = blueBuffer,
2863 .usePremultipliedAlpha = true,
2864 },
2865 },
2866 .alpha = 1.0f,
2867 .sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2868 .whitePointNits = 1000.f,
2869 };
2870
2871 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer};
2872 invokeDraw(display, layers);
2873
2874 expectBufferColor(Rect(1, 1), 0, 51, 0, 255, 1);
2875 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 255, 255);
2876}
2877
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002878TEST_P(RenderEngineTest, test_isOpaque) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002879 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002880 GTEST_SKIP();
2881 }
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002882 initializeRenderEngine();
2883
2884 const auto rect = Rect(0, 0, 1, 1);
2885 const renderengine::DisplaySettings display{
2886 .physicalDisplay = rect,
2887 .clip = rect,
2888 .outputDataspace = ui::Dataspace::DISPLAY_P3,
2889 };
2890
2891 // Create an unpremul buffer that is green with no alpha. Using isOpaque
2892 // should make the green show.
2893 const auto buf = allocateSourceBuffer(1, 1);
2894 {
2895 uint8_t* pixels;
2896 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2897 reinterpret_cast<void**>(&pixels));
2898 pixels[0] = 0;
2899 pixels[1] = 255;
2900 pixels[2] = 0;
2901 pixels[3] = 0;
2902 buf->getBuffer()->unlock();
2903 }
2904
2905 const renderengine::LayerSettings greenLayer{
2906 .geometry.boundaries = rect.toFloatRect(),
2907 .source =
2908 renderengine::PixelSource{
2909 .buffer =
2910 renderengine::Buffer{
2911 .buffer = buf,
2912 // Although the pixels are not
2913 // premultiplied in practice, this
2914 // matches the input we see.
2915 .usePremultipliedAlpha = true,
2916 .isOpaque = true,
2917 },
2918 },
2919 .alpha = 1.0f,
2920 };
2921
Sally Qi59a9f502021-10-12 18:53:23 +00002922 std::vector<renderengine::LayerSettings> layers{greenLayer};
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002923 invokeDraw(display, layers);
2924
Alec Mouri47bcb072023-08-15 02:02:49 +00002925 expectBufferColor(rect, 117, 251, 76, 255);
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002926}
Alec Mouri4049b532021-10-15 20:59:33 -07002927
Alec Mouri4049b532021-10-15 20:59:33 -07002928TEST_P(RenderEngineTest, test_tonemapPQMatches) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002929 if (!GetParam()->apiSupported()) {
Alec Mouri5a493722022-01-26 16:43:02 -08002930 GTEST_SKIP();
Alec Mouri4049b532021-10-15 20:59:33 -07002931 }
2932
Alec Mouri4049b532021-10-15 20:59:33 -07002933 initializeRenderEngine();
2934
Alec Mouri5a493722022-01-26 16:43:02 -08002935 tonemap(
2936 static_cast<ui::Dataspace>(HAL_DATASPACE_STANDARD_BT2020 |
2937 HAL_DATASPACE_TRANSFER_ST2084 | HAL_DATASPACE_RANGE_FULL),
2938 [](vec3 color) { return EOTF_PQ(color); },
2939 [](vec3 color, float) {
2940 static constexpr float kMaxPQLuminance = 10000.f;
2941 return color * kMaxPQLuminance;
2942 });
2943}
Alec Mouri4049b532021-10-15 20:59:33 -07002944
Alec Mouri5a493722022-01-26 16:43:02 -08002945TEST_P(RenderEngineTest, test_tonemapHLGMatches) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002946 if (!GetParam()->apiSupported()) {
Alec Mouri5a493722022-01-26 16:43:02 -08002947 GTEST_SKIP();
Alec Mouri4049b532021-10-15 20:59:33 -07002948 }
2949
Alec Mouri5a493722022-01-26 16:43:02 -08002950 initializeRenderEngine();
Alec Mouri4049b532021-10-15 20:59:33 -07002951
Alec Mouri5a493722022-01-26 16:43:02 -08002952 tonemap(
2953 static_cast<ui::Dataspace>(HAL_DATASPACE_STANDARD_BT2020 | HAL_DATASPACE_TRANSFER_HLG |
2954 HAL_DATASPACE_RANGE_FULL),
2955 [](vec3 color) { return EOTF_HLG(color); },
2956 [](vec3 color, float currentLuminaceNits) {
2957 static constexpr float kMaxHLGLuminance = 1000.f;
Alec Mouri7a577452022-03-04 23:41:38 +00002958 return color * kMaxHLGLuminance;
Alec Mouri5a493722022-01-26 16:43:02 -08002959 });
Alec Mouri4049b532021-10-15 20:59:33 -07002960}
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -05002961
2962TEST_P(RenderEngineTest, r8_behaves_as_mask) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002963 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002964 GTEST_SKIP();
2965 }
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -05002966 initializeRenderEngine();
2967
2968 const auto r8Buffer = allocateR8Buffer(2, 1);
2969 if (!r8Buffer) {
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05002970 GTEST_SKIP() << "Test is only necessary on devices that support r8";
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -05002971 return;
2972 }
2973 {
2974 uint8_t* pixels;
2975 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2976 reinterpret_cast<void**>(&pixels));
2977 // This will be drawn on top of a green buffer. We'll verify that 255
2978 // results in keeping the original green and 0 results in black.
2979 pixels[0] = 0;
2980 pixels[1] = 255;
2981 r8Buffer->getBuffer()->unlock();
2982 }
2983
2984 const auto rect = Rect(0, 0, 2, 1);
2985 const renderengine::DisplaySettings display{
2986 .physicalDisplay = rect,
2987 .clip = rect,
2988 .outputDataspace = ui::Dataspace::SRGB,
2989 };
2990
2991 const auto greenBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(0, 255, 0, 255));
2992 const renderengine::LayerSettings greenLayer{
2993 .geometry.boundaries = rect.toFloatRect(),
2994 .source =
2995 renderengine::PixelSource{
2996 .buffer =
2997 renderengine::Buffer{
2998 .buffer = greenBuffer,
2999 },
3000 },
3001 .alpha = 1.0f,
3002 };
3003 const renderengine::LayerSettings r8Layer{
3004 .geometry.boundaries = rect.toFloatRect(),
3005 .source =
3006 renderengine::PixelSource{
3007 .buffer =
3008 renderengine::Buffer{
3009 .buffer = r8Buffer,
3010 },
3011 },
3012 .alpha = 1.0f,
3013 };
3014
3015 std::vector<renderengine::LayerSettings> layers{greenLayer, r8Layer};
3016 invokeDraw(display, layers);
3017
3018 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 255);
3019 expectBufferColor(Rect(1, 0, 2, 1), 0, 255, 0, 255);
3020}
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003021
3022TEST_P(RenderEngineTest, r8_respects_color_transform) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05003023 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003024 GTEST_SKIP();
3025 }
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003026 initializeRenderEngine();
3027
3028 const auto r8Buffer = allocateR8Buffer(2, 1);
3029 if (!r8Buffer) {
3030 GTEST_SKIP() << "Test is only necessary on devices that support r8";
3031 return;
3032 }
3033 {
3034 uint8_t* pixels;
3035 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
3036 reinterpret_cast<void**>(&pixels));
3037 pixels[0] = 0;
3038 pixels[1] = 255;
3039 r8Buffer->getBuffer()->unlock();
3040 }
3041
3042 const auto rect = Rect(0, 0, 2, 1);
3043 const renderengine::DisplaySettings display{
3044 .physicalDisplay = rect,
3045 .clip = rect,
3046 .outputDataspace = ui::Dataspace::SRGB,
3047 // Verify that the R8 layer respects the color transform when
3048 // deviceHandlesColorTransform is false. This transform converts
3049 // pure red to pure green. That will occur when the R8 buffer is
3050 // 255. When the R8 buffer is 0, it will still change to black, as
3051 // with r8_behaves_as_mask.
Alec Mouri9bcd1d12022-04-21 22:16:56 +00003052 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003053 .deviceHandlesColorTransform = false,
3054 };
3055
3056 const auto redBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(255, 0, 0, 255));
3057 const renderengine::LayerSettings redLayer{
3058 .geometry.boundaries = rect.toFloatRect(),
3059 .source =
3060 renderengine::PixelSource{
3061 .buffer =
3062 renderengine::Buffer{
3063 .buffer = redBuffer,
3064 },
3065 },
3066 .alpha = 1.0f,
3067 };
3068 const renderengine::LayerSettings r8Layer{
3069 .geometry.boundaries = rect.toFloatRect(),
3070 .source =
3071 renderengine::PixelSource{
3072 .buffer =
3073 renderengine::Buffer{
3074 .buffer = r8Buffer,
3075 },
3076 },
3077 .alpha = 1.0f,
3078 };
3079
3080 std::vector<renderengine::LayerSettings> layers{redLayer, r8Layer};
3081 invokeDraw(display, layers);
3082
3083 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 255);
3084 expectBufferColor(Rect(1, 0, 2, 1), 0, 255, 0, 255);
3085}
3086
3087TEST_P(RenderEngineTest, r8_respects_color_transform_when_device_handles) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05003088 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003089 GTEST_SKIP();
3090 }
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003091 initializeRenderEngine();
3092
3093 const auto r8Buffer = allocateR8Buffer(2, 1);
3094 if (!r8Buffer) {
3095 GTEST_SKIP() << "Test is only necessary on devices that support r8";
3096 return;
3097 }
3098 {
3099 uint8_t* pixels;
3100 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
3101 reinterpret_cast<void**>(&pixels));
3102 pixels[0] = 0;
3103 pixels[1] = 255;
3104 r8Buffer->getBuffer()->unlock();
3105 }
3106
3107 const auto rect = Rect(0, 0, 2, 1);
3108 const renderengine::DisplaySettings display{
3109 .physicalDisplay = rect,
3110 .clip = rect,
3111 .outputDataspace = ui::Dataspace::SRGB,
3112 // If deviceHandlesColorTransform is true, pixels where the A8
3113 // buffer is opaque are unaffected. If the colorTransform is
3114 // invertible, pixels where the A8 buffer are transparent have the
3115 // inverse applied to them so that the DPU will convert them back to
3116 // black. Test with an arbitrary, invertible matrix.
3117 .colorTransform = mat4(1, 0, 0, 2,
3118 3, 1, 2, 5,
3119 0, 5, 3, 0,
3120 0, 1, 0, 2),
3121 .deviceHandlesColorTransform = true,
3122 };
3123
3124 const auto redBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(255, 0, 0, 255));
3125 const renderengine::LayerSettings redLayer{
3126 .geometry.boundaries = rect.toFloatRect(),
3127 .source =
3128 renderengine::PixelSource{
3129 .buffer =
3130 renderengine::Buffer{
3131 .buffer = redBuffer,
3132 },
3133 },
3134 .alpha = 1.0f,
3135 };
3136 const renderengine::LayerSettings r8Layer{
3137 .geometry.boundaries = rect.toFloatRect(),
3138 .source =
3139 renderengine::PixelSource{
3140 .buffer =
3141 renderengine::Buffer{
3142 .buffer = r8Buffer,
3143 },
3144 },
3145 .alpha = 1.0f,
3146 };
3147
3148 std::vector<renderengine::LayerSettings> layers{redLayer, r8Layer};
3149 invokeDraw(display, layers);
3150
3151 expectBufferColor(Rect(1, 0, 2, 1), 255, 0, 0, 255); // Still red.
3152 expectBufferColor(Rect(0, 0, 1, 1), 0, 70, 0, 255);
3153}
Leon Scroggins III45be9182022-04-27 10:37:11 -04003154
3155TEST_P(RenderEngineTest, primeShaderCache) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05003156 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003157 GTEST_SKIP();
3158 }
Leon Scroggins III45be9182022-04-27 10:37:11 -04003159 initializeRenderEngine();
3160
Bruno BELANYIb9b5b702023-10-13 13:25:11 +00003161 auto fut = mRE->primeCache(false);
Leon Scroggins III45be9182022-04-27 10:37:11 -04003162 if (fut.valid()) {
3163 fut.wait();
3164 }
3165
Alec Mouri47bcb072023-08-15 02:02:49 +00003166 static constexpr int kMinimumExpectedShadersCompiled = 60;
Leon Scroggins III45be9182022-04-27 10:37:11 -04003167 ASSERT_GT(static_cast<skia::SkiaGLRenderEngine*>(mRE.get())->reportShadersCompiled(),
Alec Mouri47bcb072023-08-15 02:02:49 +00003168 kMinimumExpectedShadersCompiled);
Leon Scroggins III45be9182022-04-27 10:37:11 -04003169}
Derek Sollenbergerd3f60652021-06-11 15:34:36 -04003170} // namespace renderengine
Alec Mouri6e57f682018-09-29 20:45:08 -07003171} // namespace android
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08003172
3173// TODO(b/129481165): remove the #pragma below and fix conversion issues
Marin Shalamanovbed7fd32020-12-21 20:02:20 +01003174#pragma clang diagnostic pop // ignored "-Wconversion -Wextra"