blob: 11d4fdebdc9d383e60df9fc3757aeb2cb9fe73cb [file] [log] [blame]
Alec Mouri6e57f682018-09-29 20:45:08 -07001/*
2 * Copyright 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Ana Krulec82ba2ec2020-11-21 13:33:20 -080017#undef LOG_TAG
18#define LOG_TAG "RenderEngineTest"
19
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -080020// TODO(b/129481165): remove the #pragma below and fix conversion issues
21#pragma clang diagnostic push
22#pragma clang diagnostic ignored "-Wconversion"
Marin Shalamanovbed7fd32020-12-21 20:02:20 +010023#pragma clang diagnostic ignored "-Wextra"
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -080024
Lucas Dupin19c8f0e2019-11-25 17:55:44 -080025#include <cutils/properties.h>
Ana Krulec9bc9dc62020-02-26 12:16:40 -080026#include <gtest/gtest.h>
Alec Mouria90a5702021-04-16 16:36:21 +000027#include <renderengine/ExternalTexture.h>
Alec Mouri6e57f682018-09-29 20:45:08 -070028#include <renderengine/RenderEngine.h>
Vishnu Nairdbbe3852022-01-12 20:22:11 -080029#include <renderengine/impl/ExternalTexture.h>
Alec Mouri1089aed2018-10-25 21:33:57 -070030#include <sync/sync.h>
Alec Mouri4049b532021-10-15 20:59:33 -070031#include <system/graphics-base-v1.0.h>
32#include <tonemap/tonemap.h>
33#include <ui/ColorSpace.h>
Alec Mouri6e57f682018-09-29 20:45:08 -070034#include <ui/PixelFormat.h>
Alec Mouric0aae732021-01-12 13:32:18 -080035
36#include <chrono>
37#include <condition_variable>
38#include <fstream>
39
Alec Mouric0aae732021-01-12 13:32:18 -080040#include "../skia/SkiaGLRenderEngine.h"
Ian Elliott1f0911e2022-09-09 16:31:47 -060041#include "../skia/SkiaVkRenderEngine.h"
Ana Krulec9bc9dc62020-02-26 12:16:40 -080042#include "../threaded/RenderEngineThreaded.h"
Alec Mouri6e57f682018-09-29 20:45:08 -070043
Alec Mouri1089aed2018-10-25 21:33:57 -070044constexpr int DEFAULT_DISPLAY_WIDTH = 128;
45constexpr int DEFAULT_DISPLAY_HEIGHT = 256;
46constexpr int DEFAULT_DISPLAY_OFFSET = 64;
Vishnu Nair16efdbf2019-12-10 11:55:42 -080047constexpr bool WRITE_BUFFER_TO_FILE_ON_FAILURE = false;
Alec Mouri1089aed2018-10-25 21:33:57 -070048
Alec Mouri6e57f682018-09-29 20:45:08 -070049namespace android {
Derek Sollenbergerd3f60652021-06-11 15:34:36 -040050namespace renderengine {
Alec Mouri6e57f682018-09-29 20:45:08 -070051
Alec Mouri5a493722022-01-26 16:43:02 -080052namespace {
53
54double EOTF_PQ(double channel) {
55 float m1 = (2610.0 / 4096.0) / 4.0;
56 float m2 = (2523.0 / 4096.0) * 128.0;
57 float c1 = (3424.0 / 4096.0);
58 float c2 = (2413.0 / 4096.0) * 32.0;
59 float c3 = (2392.0 / 4096.0) * 32.0;
60
61 float tmp = std::pow(std::clamp(channel, 0.0, 1.0), 1.0 / m2);
62 tmp = std::fmax(tmp - c1, 0.0) / (c2 - c3 * tmp);
63 return std::pow(tmp, 1.0 / m1);
64}
65
66vec3 EOTF_PQ(vec3 color) {
67 return vec3(EOTF_PQ(color.r), EOTF_PQ(color.g), EOTF_PQ(color.b));
68}
69
70double EOTF_HLG(double channel) {
71 const float a = 0.17883277;
72 const float b = 0.28466892;
73 const float c = 0.55991073;
74 return channel <= 0.5 ? channel * channel / 3.0 : (exp((channel - c) / a) + b) / 12.0;
75}
76
77vec3 EOTF_HLG(vec3 color) {
78 return vec3(EOTF_HLG(color.r), EOTF_HLG(color.g), EOTF_HLG(color.b));
79}
80
81double OETF_sRGB(double channel) {
82 return channel <= 0.0031308 ? channel * 12.92 : (pow(channel, 1.0 / 2.4) * 1.055) - 0.055;
83}
84
85int sign(float in) {
86 return in >= 0.0 ? 1 : -1;
87}
88
89vec3 OETF_sRGB(vec3 linear) {
90 return vec3(sign(linear.r) * OETF_sRGB(linear.r), sign(linear.g) * OETF_sRGB(linear.g),
91 sign(linear.b) * OETF_sRGB(linear.b));
92}
93
Alec Mouri9bcd1d12022-04-21 22:16:56 +000094// clang-format off
95// Converts red channels to green channels, and zeroes out an existing green channel.
96static const auto kRemoveGreenAndMoveRedToGreenMat4 = mat4(0, 1, 0, 0,
97 0, 0, 0, 0,
98 0, 0, 1, 0,
99 0, 0, 0, 1);
100// clang-format on
101
Alec Mouri5a493722022-01-26 16:43:02 -0800102} // namespace
103
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800104class RenderEngineFactory {
105public:
106 virtual ~RenderEngineFactory() = default;
107
108 virtual std::string name() = 0;
Alec Mouric0aae732021-01-12 13:32:18 -0800109 virtual renderengine::RenderEngine::RenderEngineType type() = 0;
110 virtual std::unique_ptr<renderengine::RenderEngine> createRenderEngine() = 0;
Ian Elliott1f0911e2022-09-09 16:31:47 -0600111 virtual bool typeSupported() = 0;
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800112};
113
Ian Elliott1f0911e2022-09-09 16:31:47 -0600114class SkiaVkRenderEngineFactory : public RenderEngineFactory {
115public:
116 std::string name() override { return "SkiaVkRenderEngineFactory"; }
117
118 renderengine::RenderEngine::RenderEngineType type() {
119 return renderengine::RenderEngine::RenderEngineType::SKIA_VK;
120 }
121
122 std::unique_ptr<renderengine::RenderEngine> createRenderEngine() override {
123 std::unique_ptr<renderengine::RenderEngine> re = createSkiaVkRenderEngine();
124 return re;
125 }
126
127 std::unique_ptr<renderengine::skia::SkiaVkRenderEngine> createSkiaVkRenderEngine() {
128 renderengine::RenderEngineCreationArgs reCreationArgs =
129 renderengine::RenderEngineCreationArgs::Builder()
130 .setPixelFormat(static_cast<int>(ui::PixelFormat::RGBA_8888))
131 .setImageCacheSize(1)
Ian Elliott1f0911e2022-09-09 16:31:47 -0600132 .setEnableProtectedContext(false)
133 .setPrecacheToneMapperShaderOnly(false)
134 .setSupportsBackgroundBlur(true)
135 .setContextPriority(renderengine::RenderEngine::ContextPriority::MEDIUM)
136 .setRenderEngineType(type())
Ian Elliott1f0911e2022-09-09 16:31:47 -0600137 .build();
138 return renderengine::skia::SkiaVkRenderEngine::create(reCreationArgs);
139 }
140
141 bool typeSupported() override {
142 return skia::SkiaVkRenderEngine::canSupportSkiaVkRenderEngine();
143 }
Ian Elliott1f0911e2022-09-09 16:31:47 -0600144 void skip() { GTEST_SKIP(); }
145};
146
Alec Mouri0eab3e82020-12-08 18:10:27 -0800147class SkiaGLESRenderEngineFactory : public RenderEngineFactory {
148public:
Alec Mouric0aae732021-01-12 13:32:18 -0800149 std::string name() override { return "SkiaGLRenderEngineFactory"; }
Alec Mouri0eab3e82020-12-08 18:10:27 -0800150
Alec Mouric0aae732021-01-12 13:32:18 -0800151 renderengine::RenderEngine::RenderEngineType type() {
152 return renderengine::RenderEngine::RenderEngineType::SKIA_GL;
153 }
154
155 std::unique_ptr<renderengine::RenderEngine> createRenderEngine() override {
Alec Mouri0eab3e82020-12-08 18:10:27 -0800156 renderengine::RenderEngineCreationArgs reCreationArgs =
157 renderengine::RenderEngineCreationArgs::Builder()
158 .setPixelFormat(static_cast<int>(ui::PixelFormat::RGBA_8888))
159 .setImageCacheSize(1)
160 .setEnableProtectedContext(false)
161 .setPrecacheToneMapperShaderOnly(false)
162 .setSupportsBackgroundBlur(true)
163 .setContextPriority(renderengine::RenderEngine::ContextPriority::MEDIUM)
Alec Mouric0aae732021-01-12 13:32:18 -0800164 .setRenderEngineType(type())
Alec Mouri0eab3e82020-12-08 18:10:27 -0800165 .build();
Alec Mouric0aae732021-01-12 13:32:18 -0800166 return renderengine::skia::SkiaGLRenderEngine::create(reCreationArgs);
Alec Mouri0eab3e82020-12-08 18:10:27 -0800167 }
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -0400168
Ian Elliott1f0911e2022-09-09 16:31:47 -0600169 bool typeSupported() override { return true; }
Alec Mouri0eab3e82020-12-08 18:10:27 -0800170};
171
172class SkiaGLESCMRenderEngineFactory : public RenderEngineFactory {
173public:
Alec Mouric0aae732021-01-12 13:32:18 -0800174 std::string name() override { return "SkiaGLCMRenderEngineFactory"; }
Alec Mouri0eab3e82020-12-08 18:10:27 -0800175
Alec Mouric0aae732021-01-12 13:32:18 -0800176 renderengine::RenderEngine::RenderEngineType type() {
177 return renderengine::RenderEngine::RenderEngineType::SKIA_GL;
178 }
179
180 std::unique_ptr<renderengine::RenderEngine> createRenderEngine() override {
Alec Mouri0eab3e82020-12-08 18:10:27 -0800181 renderengine::RenderEngineCreationArgs reCreationArgs =
182 renderengine::RenderEngineCreationArgs::Builder()
183 .setPixelFormat(static_cast<int>(ui::PixelFormat::RGBA_8888))
184 .setImageCacheSize(1)
185 .setEnableProtectedContext(false)
186 .setPrecacheToneMapperShaderOnly(false)
187 .setSupportsBackgroundBlur(true)
188 .setContextPriority(renderengine::RenderEngine::ContextPriority::MEDIUM)
Alec Mouric0aae732021-01-12 13:32:18 -0800189 .setRenderEngineType(type())
Alec Mouri0eab3e82020-12-08 18:10:27 -0800190 .build();
Alec Mouric0aae732021-01-12 13:32:18 -0800191 return renderengine::skia::SkiaGLRenderEngine::create(reCreationArgs);
Alec Mouri0eab3e82020-12-08 18:10:27 -0800192 }
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -0400193
Ian Elliott1f0911e2022-09-09 16:31:47 -0600194 bool typeSupported() override { return true; }
Alec Mouri0eab3e82020-12-08 18:10:27 -0800195};
196
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800197class RenderEngineTest : public ::testing::TestWithParam<std::shared_ptr<RenderEngineFactory>> {
198public:
Alec Mouria90a5702021-04-16 16:36:21 +0000199 std::shared_ptr<renderengine::ExternalTexture> allocateDefaultBuffer() {
200 return std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800201 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -0700202 ExternalTexture>(sp<GraphicBuffer>::
203 make(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT,
204 HAL_PIXEL_FORMAT_RGBA_8888, 1,
205 GRALLOC_USAGE_SW_READ_OFTEN |
206 GRALLOC_USAGE_SW_WRITE_OFTEN |
207 GRALLOC_USAGE_HW_RENDER |
208 GRALLOC_USAGE_HW_TEXTURE,
209 "output"),
Alec Mouria90a5702021-04-16 16:36:21 +0000210 *mRE,
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800211 renderengine::impl::ExternalTexture::Usage::READABLE |
212 renderengine::impl::ExternalTexture::Usage::
213 WRITEABLE);
Alec Mouri6e57f682018-09-29 20:45:08 -0700214 }
215
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800216 // Allocates a 1x1 buffer to fill with a solid color
Alec Mouria90a5702021-04-16 16:36:21 +0000217 std::shared_ptr<renderengine::ExternalTexture> allocateSourceBuffer(uint32_t width,
218 uint32_t height) {
219 return std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800220 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -0700221 ExternalTexture>(sp<GraphicBuffer>::
222 make(width, height, HAL_PIXEL_FORMAT_RGBA_8888, 1,
223 GRALLOC_USAGE_SW_READ_OFTEN |
224 GRALLOC_USAGE_SW_WRITE_OFTEN |
225 GRALLOC_USAGE_HW_TEXTURE,
226 "input"),
Alec Mouria90a5702021-04-16 16:36:21 +0000227 *mRE,
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800228 renderengine::impl::ExternalTexture::Usage::READABLE |
229 renderengine::impl::ExternalTexture::Usage::
230 WRITEABLE);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800231 }
232
Alec Mouricdf6cbc2021-11-01 17:21:15 -0700233 std::shared_ptr<renderengine::ExternalTexture> allocateAndFillSourceBuffer(uint32_t width,
234 uint32_t height,
235 ubyte4 color) {
236 const auto buffer = allocateSourceBuffer(width, height);
237 uint8_t* pixels;
238 buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
239 reinterpret_cast<void**>(&pixels));
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -0500240 for (uint32_t j = 0; j < height; j++) {
241 uint8_t* dst = pixels + (buffer->getBuffer()->getStride() * j * 4);
242 for (uint32_t i = 0; i < width; i++) {
243 dst[0] = color.r;
244 dst[1] = color.g;
245 dst[2] = color.b;
246 dst[3] = color.a;
247 dst += 4;
248 }
249 }
Alec Mouricdf6cbc2021-11-01 17:21:15 -0700250 buffer->getBuffer()->unlock();
251 return buffer;
252 }
253
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -0500254 std::shared_ptr<renderengine::ExternalTexture> allocateR8Buffer(int width, int height) {
Ady Abrahamd11bade2022-08-01 16:18:03 -0700255 const auto kUsageFlags =
256 static_cast<uint64_t>(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
257 GRALLOC_USAGE_HW_TEXTURE);
258 auto buffer =
259 sp<GraphicBuffer>::make(static_cast<uint32_t>(width), static_cast<uint32_t>(height),
260 android::PIXEL_FORMAT_R_8, 1u, kUsageFlags, "r8");
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -0500261 if (buffer->initCheck() != 0) {
262 // Devices are not required to support R8.
263 return nullptr;
264 }
265 return std::make_shared<
266 renderengine::impl::ExternalTexture>(std::move(buffer), *mRE,
267 renderengine::impl::ExternalTexture::Usage::
268 READABLE);
269 }
270
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800271 RenderEngineTest() {
272 const ::testing::TestInfo* const test_info =
273 ::testing::UnitTest::GetInstance()->current_test_info();
274 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800275 }
Alec Mouri1089aed2018-10-25 21:33:57 -0700276
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800277 ~RenderEngineTest() {
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800278 if (WRITE_BUFFER_TO_FILE_ON_FAILURE && ::testing::Test::HasFailure()) {
279 writeBufferToFile("/data/texture_out_");
280 }
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800281 const ::testing::TestInfo* const test_info =
282 ::testing::UnitTest::GetInstance()->current_test_info();
283 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800284 }
285
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800286 void writeBufferToFile(const char* basename) {
287 std::string filename(basename);
288 filename.append(::testing::UnitTest::GetInstance()->current_test_info()->name());
289 filename.append(".ppm");
290 std::ofstream file(filename.c_str(), std::ios::binary);
291 if (!file.is_open()) {
292 ALOGE("Unable to open file: %s", filename.c_str());
293 ALOGE("You may need to do: \"adb shell setenforce 0\" to enable "
294 "surfaceflinger to write debug images");
295 return;
296 }
297
Alec Mouri1089aed2018-10-25 21:33:57 -0700298 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +0000299 mBuffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
300 reinterpret_cast<void**>(&pixels));
Alec Mouri1089aed2018-10-25 21:33:57 -0700301
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800302 file << "P6\n";
Alec Mouria90a5702021-04-16 16:36:21 +0000303 file << mBuffer->getBuffer()->getWidth() << "\n";
304 file << mBuffer->getBuffer()->getHeight() << "\n";
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800305 file << 255 << "\n";
306
Alec Mouria90a5702021-04-16 16:36:21 +0000307 std::vector<uint8_t> outBuffer(mBuffer->getBuffer()->getWidth() *
308 mBuffer->getBuffer()->getHeight() * 3);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800309 auto outPtr = reinterpret_cast<uint8_t*>(outBuffer.data());
310
Alec Mouria90a5702021-04-16 16:36:21 +0000311 for (int32_t j = 0; j < mBuffer->getBuffer()->getHeight(); j++) {
312 const uint8_t* src = pixels + (mBuffer->getBuffer()->getStride() * j) * 4;
313 for (int32_t i = 0; i < mBuffer->getBuffer()->getWidth(); i++) {
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800314 // Only copy R, G and B components
315 outPtr[0] = src[0];
316 outPtr[1] = src[1];
317 outPtr[2] = src[2];
318 outPtr += 3;
319
320 src += 4;
321 }
322 }
323 file.write(reinterpret_cast<char*>(outBuffer.data()), outBuffer.size());
Alec Mouria90a5702021-04-16 16:36:21 +0000324 mBuffer->getBuffer()->unlock();
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800325 }
326
327 void expectBufferColor(const Region& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
328 size_t c;
329 Rect const* rect = region.getArray(&c);
330 for (size_t i = 0; i < c; i++, rect++) {
331 expectBufferColor(*rect, r, g, b, a);
332 }
333 }
334
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -0400335 void expectBufferColor(const Point& point, uint8_t r, uint8_t g, uint8_t b, uint8_t a,
336 uint8_t tolerance = 0) {
337 expectBufferColor(Rect(point.x, point.y, point.x + 1, point.y + 1), r, g, b, a, tolerance);
338 }
339
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800340 void expectBufferColor(const Rect& rect, uint8_t r, uint8_t g, uint8_t b, uint8_t a,
341 uint8_t tolerance = 0) {
Alec Mouri4049b532021-10-15 20:59:33 -0700342 auto generator = [=](Point) { return ubyte4(r, g, b, a); };
343 expectBufferColor(rect, generator, tolerance);
344 }
345
346 using ColorGenerator = std::function<ubyte4(Point location)>;
347
348 void expectBufferColor(const Rect& rect, ColorGenerator generator, uint8_t tolerance = 0) {
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800349 auto colorCompare = [tolerance](const uint8_t* colorA, const uint8_t* colorB) {
350 auto colorBitCompare = [tolerance](uint8_t a, uint8_t b) {
351 uint8_t tmp = a >= b ? a - b : b - a;
352 return tmp <= tolerance;
353 };
354 return std::equal(colorA, colorA + 4, colorB, colorBitCompare);
Alec Mouri1089aed2018-10-25 21:33:57 -0700355 };
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800356
Alec Mouri4049b532021-10-15 20:59:33 -0700357 expectBufferColor(rect, generator, colorCompare);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800358 }
359
Alec Mouri4049b532021-10-15 20:59:33 -0700360 void expectBufferColor(const Rect& region, ColorGenerator generator,
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800361 std::function<bool(const uint8_t* a, const uint8_t* b)> colorCompare) {
362 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +0000363 mBuffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
364 reinterpret_cast<void**>(&pixels));
Alec Mouri1089aed2018-10-25 21:33:57 -0700365 int32_t maxFails = 10;
366 int32_t fails = 0;
367 for (int32_t j = 0; j < region.getHeight(); j++) {
Alec Mouria90a5702021-04-16 16:36:21 +0000368 const uint8_t* src = pixels +
369 (mBuffer->getBuffer()->getStride() * (region.top + j) + region.left) * 4;
Alec Mouri1089aed2018-10-25 21:33:57 -0700370 for (int32_t i = 0; i < region.getWidth(); i++) {
Alec Mouri4049b532021-10-15 20:59:33 -0700371 const auto location = Point(region.left + i, region.top + j);
372 const ubyte4 colors = generator(location);
373 const uint8_t expected[4] = {colors.r, colors.g, colors.b, colors.a};
374 bool colorMatches = colorCompare(src, expected);
375 EXPECT_TRUE(colorMatches)
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -0400376 << GetParam()->name().c_str() << ": "
Alec Mouri4049b532021-10-15 20:59:33 -0700377 << "pixel @ (" << location.x << ", " << location.y << "): "
378 << "expected (" << static_cast<uint32_t>(colors.r) << ", "
379 << static_cast<uint32_t>(colors.g) << ", "
380 << static_cast<uint32_t>(colors.b) << ", "
381 << static_cast<uint32_t>(colors.a) << "), "
Alec Mouri1089aed2018-10-25 21:33:57 -0700382 << "got (" << static_cast<uint32_t>(src[0]) << ", "
383 << static_cast<uint32_t>(src[1]) << ", " << static_cast<uint32_t>(src[2])
384 << ", " << static_cast<uint32_t>(src[3]) << ")";
385 src += 4;
Alec Mouri4049b532021-10-15 20:59:33 -0700386 if (!colorMatches && ++fails >= maxFails) {
Alec Mouri1089aed2018-10-25 21:33:57 -0700387 break;
388 }
389 }
390 if (fails >= maxFails) {
391 break;
392 }
393 }
Alec Mouria90a5702021-04-16 16:36:21 +0000394 mBuffer->getBuffer()->unlock();
Alec Mouri1089aed2018-10-25 21:33:57 -0700395 }
396
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800397 void expectAlpha(const Rect& rect, uint8_t a) {
Alec Mouri4049b532021-10-15 20:59:33 -0700398 auto generator = [=](Point) { return ubyte4(0, 0, 0, a); };
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800399 auto colorCompare = [](const uint8_t* colorA, const uint8_t* colorB) {
400 return colorA[3] == colorB[3];
401 };
Alec Mouri4049b532021-10-15 20:59:33 -0700402 expectBufferColor(rect, generator, colorCompare);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800403 }
404
405 void expectShadowColor(const renderengine::LayerSettings& castingLayer,
Vishnu Naird9e4f462023-10-06 04:05:45 +0000406 const ShadowSettings& shadow, const ubyte4& casterColor,
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800407 const ubyte4& backgroundColor) {
408 const Rect casterRect(castingLayer.geometry.boundaries);
409 Region casterRegion = Region(casterRect);
Vishnu Nair50c0afe2022-07-11 15:04:07 -0700410 const float casterCornerRadius = (castingLayer.geometry.roundedCornersRadius.x +
411 castingLayer.geometry.roundedCornersRadius.y) /
412 2.0;
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800413 if (casterCornerRadius > 0.0f) {
414 // ignore the corners if a corner radius is set
415 Rect cornerRect(casterCornerRadius, casterCornerRadius);
416 casterRegion.subtractSelf(cornerRect.offsetTo(casterRect.left, casterRect.top));
417 casterRegion.subtractSelf(
418 cornerRect.offsetTo(casterRect.right - casterCornerRadius, casterRect.top));
419 casterRegion.subtractSelf(
420 cornerRect.offsetTo(casterRect.left, casterRect.bottom - casterCornerRadius));
421 casterRegion.subtractSelf(cornerRect.offsetTo(casterRect.right - casterCornerRadius,
422 casterRect.bottom - casterCornerRadius));
423 }
424
425 const float shadowInset = shadow.length * -1.0f;
426 const Rect casterWithShadow =
427 Rect(casterRect).inset(shadowInset, shadowInset, shadowInset, shadowInset);
428 const Region shadowRegion = Region(casterWithShadow).subtractSelf(casterRect);
429 const Region backgroundRegion = Region(fullscreenRect()).subtractSelf(casterWithShadow);
430
431 // verify casting layer
432 expectBufferColor(casterRegion, casterColor.r, casterColor.g, casterColor.b, casterColor.a);
433
434 // verify shadows by testing just the alpha since its difficult to validate the shadow color
435 size_t c;
436 Rect const* r = shadowRegion.getArray(&c);
437 for (size_t i = 0; i < c; i++, r++) {
438 expectAlpha(*r, 255);
439 }
440
441 // verify background
442 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
443 backgroundColor.a);
444 }
445
Vishnu Naird9e4f462023-10-06 04:05:45 +0000446 void expectShadowColorWithoutCaster(const FloatRect& casterBounds, const ShadowSettings& shadow,
Alec Mouribd17b3b2020-12-17 11:08:30 -0800447 const ubyte4& backgroundColor) {
448 const float shadowInset = shadow.length * -1.0f;
449 const Rect casterRect(casterBounds);
450 const Rect shadowRect =
451 Rect(casterRect).inset(shadowInset, shadowInset, shadowInset, shadowInset);
452
453 const Region backgroundRegion =
454 Region(fullscreenRect()).subtractSelf(casterRect).subtractSelf(shadowRect);
455
456 expectAlpha(shadowRect, 255);
457 // (0, 0, 0) fill on the bounds of the layer should be ignored.
458 expectBufferColor(casterRect, 255, 255, 255, 255, 254);
459
460 // verify background
461 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
462 backgroundColor.a);
463 }
464
Vishnu Naird9e4f462023-10-06 04:05:45 +0000465 static ShadowSettings getShadowSettings(const vec2& casterPos, float shadowLength,
466 bool casterIsTranslucent) {
467 ShadowSettings shadow;
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800468 shadow.ambientColor = {0.0f, 0.0f, 0.0f, 0.039f};
469 shadow.spotColor = {0.0f, 0.0f, 0.0f, 0.19f};
470 shadow.lightPos = vec3(casterPos.x, casterPos.y, 0);
471 shadow.lightRadius = 0.0f;
472 shadow.length = shadowLength;
473 shadow.casterIsTranslucent = casterIsTranslucent;
474 return shadow;
475 }
476
Alec Mouri1089aed2018-10-25 21:33:57 -0700477 static Rect fullscreenRect() { return Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT); }
478
479 static Rect offsetRect() {
480 return Rect(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_WIDTH,
481 DEFAULT_DISPLAY_HEIGHT);
482 }
483
484 static Rect offsetRectAtZero() {
485 return Rect(DEFAULT_DISPLAY_WIDTH - DEFAULT_DISPLAY_OFFSET,
486 DEFAULT_DISPLAY_HEIGHT - DEFAULT_DISPLAY_OFFSET);
487 }
488
Sally Qi59a9f502021-10-12 18:53:23 +0000489 void invokeDraw(const renderengine::DisplaySettings& settings,
490 const std::vector<renderengine::LayerSettings>& layers) {
Patrick Williams2e9748f2022-08-09 22:48:18 +0000491 ftl::Future<FenceResult> future =
Alec Mourif29700f2023-08-17 21:53:31 +0000492 mRE->drawLayers(settings, layers, mBuffer, base::unique_fd());
Patrick Williams2e9748f2022-08-09 22:48:18 +0000493 ASSERT_TRUE(future.valid());
Sally Qi59a9f502021-10-12 18:53:23 +0000494
Patrick Williams2e9748f2022-08-09 22:48:18 +0000495 auto result = future.get();
496 ASSERT_TRUE(result.ok());
Alec Mouri1089aed2018-10-25 21:33:57 -0700497
Patrick Williams2e9748f2022-08-09 22:48:18 +0000498 auto fence = result.value();
499 fence->waitForever(LOG_TAG);
Alec Mouri1089aed2018-10-25 21:33:57 -0700500 }
501
Alec Mourid43ccab2019-03-13 12:23:45 -0700502 void drawEmptyLayers() {
Alec Mouri6e57f682018-09-29 20:45:08 -0700503 renderengine::DisplaySettings settings;
Sally Qi59a9f502021-10-12 18:53:23 +0000504 std::vector<renderengine::LayerSettings> layers;
Alec Mouric0aae732021-01-12 13:32:18 -0800505 invokeDraw(settings, layers);
Alec Mouri6e57f682018-09-29 20:45:08 -0700506 }
507
Alec Mouri1089aed2018-10-25 21:33:57 -0700508 template <typename SourceVariant>
509 void fillBuffer(half r, half g, half b, half a);
510
511 template <typename SourceVariant>
512 void fillRedBuffer();
513
514 template <typename SourceVariant>
515 void fillGreenBuffer();
516
517 template <typename SourceVariant>
518 void fillBlueBuffer();
519
520 template <typename SourceVariant>
521 void fillRedTransparentBuffer();
522
523 template <typename SourceVariant>
524 void fillRedOffsetBuffer();
525
526 template <typename SourceVariant>
527 void fillBufferPhysicalOffset();
528
529 template <typename SourceVariant>
Alec Mouri5a6d8572020-03-23 23:56:15 -0700530 void fillBufferCheckers(uint32_t rotation);
Alec Mouri1089aed2018-10-25 21:33:57 -0700531
532 template <typename SourceVariant>
533 void fillBufferCheckersRotate0();
534
535 template <typename SourceVariant>
536 void fillBufferCheckersRotate90();
537
538 template <typename SourceVariant>
539 void fillBufferCheckersRotate180();
540
541 template <typename SourceVariant>
542 void fillBufferCheckersRotate270();
543
544 template <typename SourceVariant>
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800545 void fillBufferWithLayerTransform();
546
547 template <typename SourceVariant>
Alec Mouri1089aed2018-10-25 21:33:57 -0700548 void fillBufferLayerTransform();
549
550 template <typename SourceVariant>
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800551 void fillBufferWithColorTransform();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800552
553 template <typename SourceVariant>
Alec Mouri1089aed2018-10-25 21:33:57 -0700554 void fillBufferColorTransform();
555
Alec Mouri7c94edb2018-12-03 21:23:26 -0800556 template <typename SourceVariant>
Sally Qi2019fd22021-11-22 10:19:04 -0800557 void fillBufferWithColorTransformAndSourceDataspace(const ui::Dataspace sourceDataspace);
558
559 template <typename SourceVariant>
560 void fillBufferColorTransformAndSourceDataspace();
561
562 template <typename SourceVariant>
563 void fillBufferWithColorTransformAndOutputDataspace(const ui::Dataspace outputDataspace);
564
565 template <typename SourceVariant>
566 void fillBufferColorTransformAndOutputDataspace();
567
568 template <typename SourceVariant>
KaiChieh Chuangda2845c2020-12-14 16:49:38 +0800569 void fillBufferWithColorTransformZeroLayerAlpha();
570
571 template <typename SourceVariant>
572 void fillBufferColorTransformZeroLayerAlpha();
573
574 template <typename SourceVariant>
Alec Mouri7c94edb2018-12-03 21:23:26 -0800575 void fillRedBufferWithRoundedCorners();
576
577 template <typename SourceVariant>
578 void fillBufferWithRoundedCorners();
579
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000580 template <typename SourceVariant>
Lucas Dupin19c8f0e2019-11-25 17:55:44 -0800581 void fillBufferAndBlurBackground();
582
583 template <typename SourceVariant>
Alec Mourie8489fd2021-04-29 16:08:56 -0700584 void fillSmallLayerAndBlurBackground();
585
586 template <typename SourceVariant>
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000587 void overlayCorners();
588
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800589 void fillRedBufferTextureTransform();
590
591 void fillBufferTextureTransform();
592
593 void fillRedBufferWithPremultiplyAlpha();
594
595 void fillBufferWithPremultiplyAlpha();
596
597 void fillRedBufferWithoutPremultiplyAlpha();
598
599 void fillBufferWithoutPremultiplyAlpha();
600
Alec Mouriac335532018-11-12 15:01:33 -0800601 void fillGreenColorBufferThenClearRegion();
602
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800603 template <typename SourceVariant>
Vishnu Naird9e4f462023-10-06 04:05:45 +0000604 void drawShadow(const renderengine::LayerSettings& castingLayer, const ShadowSettings& shadow,
605 const ubyte4& casterColor, const ubyte4& backgroundColor);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800606
Vishnu Naird9e4f462023-10-06 04:05:45 +0000607 void drawShadowWithoutCaster(const FloatRect& castingBounds, const ShadowSettings& shadow,
Alec Mouribd17b3b2020-12-17 11:08:30 -0800608 const ubyte4& backgroundColor);
609
Alec Mouri5a493722022-01-26 16:43:02 -0800610 // Tonemaps grey values from sourceDataspace -> Display P3 and checks that GPU and CPU
611 // implementations are identical Also implicitly checks that the injected tonemap shader
612 // compiles
613 void tonemap(ui::Dataspace sourceDataspace, std::function<vec3(vec3)> eotf,
614 std::function<vec3(vec3, float)> scaleOotf);
615
Alec Mouric0aae732021-01-12 13:32:18 -0800616 void initializeRenderEngine();
617
618 std::unique_ptr<renderengine::RenderEngine> mRE;
Alec Mouria90a5702021-04-16 16:36:21 +0000619 std::shared_ptr<renderengine::ExternalTexture> mBuffer;
Alec Mouri6e57f682018-09-29 20:45:08 -0700620};
621
Alec Mouric0aae732021-01-12 13:32:18 -0800622void RenderEngineTest::initializeRenderEngine() {
623 const auto& renderEngineFactory = GetParam();
Alec Mouric16974e2022-09-13 17:35:48 +0000624 mRE = renderEngineFactory->createRenderEngine();
Alec Mouria90a5702021-04-16 16:36:21 +0000625 mBuffer = allocateDefaultBuffer();
Alec Mouric0aae732021-01-12 13:32:18 -0800626}
627
Alec Mouri1089aed2018-10-25 21:33:57 -0700628struct ColorSourceVariant {
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800629 static void fillColor(renderengine::LayerSettings& layer, half r, half g, half b,
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800630 RenderEngineTest* /*fixture*/) {
Alec Mouri1089aed2018-10-25 21:33:57 -0700631 layer.source.solidColor = half3(r, g, b);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800632 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700633 }
634};
635
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800636struct RelaxOpaqueBufferVariant {
637 static void setOpaqueBit(renderengine::LayerSettings& layer) {
638 layer.source.buffer.isOpaque = false;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800639 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800640 }
641
642 static uint8_t getAlphaChannel() { return 255; }
643};
644
645struct ForceOpaqueBufferVariant {
646 static void setOpaqueBit(renderengine::LayerSettings& layer) {
647 layer.source.buffer.isOpaque = true;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800648 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800649 }
650
651 static uint8_t getAlphaChannel() {
652 // The isOpaque bit will override the alpha channel, so this should be
653 // arbitrary.
Alec Mouric0aae732021-01-12 13:32:18 -0800654 return 50;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800655 }
656};
657
658template <typename OpaquenessVariant>
659struct BufferSourceVariant {
660 static void fillColor(renderengine::LayerSettings& layer, half r, half g, half b,
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800661 RenderEngineTest* fixture) {
Alec Mouria90a5702021-04-16 16:36:21 +0000662 const auto buf = fixture->allocateSourceBuffer(1, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800663
664 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +0000665 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
666 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800667
Alec Mouria90a5702021-04-16 16:36:21 +0000668 for (int32_t j = 0; j < buf->getBuffer()->getHeight(); j++) {
669 uint8_t* iter = pixels + (buf->getBuffer()->getStride() * j) * 4;
670 for (int32_t i = 0; i < buf->getBuffer()->getWidth(); i++) {
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800671 iter[0] = uint8_t(r * 255);
672 iter[1] = uint8_t(g * 255);
673 iter[2] = uint8_t(b * 255);
674 iter[3] = OpaquenessVariant::getAlphaChannel();
675 iter += 4;
676 }
677 }
678
Alec Mouria90a5702021-04-16 16:36:21 +0000679 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800680
681 layer.source.buffer.buffer = buf;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800682 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800683 OpaquenessVariant::setOpaqueBit(layer);
684 }
685};
686
Alec Mouri1089aed2018-10-25 21:33:57 -0700687template <typename SourceVariant>
688void RenderEngineTest::fillBuffer(half r, half g, half b, half a) {
689 renderengine::DisplaySettings settings;
690 settings.physicalDisplay = fullscreenRect();
691 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800692 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700693
Sally Qi59a9f502021-10-12 18:53:23 +0000694 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700695
696 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800697 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700698 layer.geometry.boundaries = fullscreenRect().toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800699 SourceVariant::fillColor(layer, r, g, b, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700700 layer.alpha = a;
701
Sally Qi59a9f502021-10-12 18:53:23 +0000702 layers.push_back(layer);
Alec Mouri1089aed2018-10-25 21:33:57 -0700703
Alec Mouric0aae732021-01-12 13:32:18 -0800704 invokeDraw(settings, layers);
Alec Mouri1089aed2018-10-25 21:33:57 -0700705}
706
707template <typename SourceVariant>
708void RenderEngineTest::fillRedBuffer() {
709 fillBuffer<SourceVariant>(1.0f, 0.0f, 0.0f, 1.0f);
710 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
711}
712
713template <typename SourceVariant>
714void RenderEngineTest::fillGreenBuffer() {
715 fillBuffer<SourceVariant>(0.0f, 1.0f, 0.0f, 1.0f);
716 expectBufferColor(fullscreenRect(), 0, 255, 0, 255);
717}
718
719template <typename SourceVariant>
720void RenderEngineTest::fillBlueBuffer() {
721 fillBuffer<SourceVariant>(0.0f, 0.0f, 1.0f, 1.0f);
722 expectBufferColor(fullscreenRect(), 0, 0, 255, 255);
723}
724
725template <typename SourceVariant>
726void RenderEngineTest::fillRedTransparentBuffer() {
727 fillBuffer<SourceVariant>(1.0f, 0.0f, 0.0f, .2f);
728 expectBufferColor(fullscreenRect(), 51, 0, 0, 51);
729}
730
731template <typename SourceVariant>
732void RenderEngineTest::fillRedOffsetBuffer() {
733 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800734 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700735 settings.physicalDisplay = offsetRect();
736 settings.clip = offsetRectAtZero();
737
Sally Qi59a9f502021-10-12 18:53:23 +0000738 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700739
740 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800741 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700742 layer.geometry.boundaries = offsetRectAtZero().toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800743 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700744 layer.alpha = 1.0f;
745
Sally Qi59a9f502021-10-12 18:53:23 +0000746 layers.push_back(layer);
Alec Mouric0aae732021-01-12 13:32:18 -0800747 invokeDraw(settings, layers);
Alec Mouri1089aed2018-10-25 21:33:57 -0700748}
749
750template <typename SourceVariant>
751void RenderEngineTest::fillBufferPhysicalOffset() {
752 fillRedOffsetBuffer<SourceVariant>();
753
754 expectBufferColor(Rect(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_WIDTH,
755 DEFAULT_DISPLAY_HEIGHT),
756 255, 0, 0, 255);
757 Rect offsetRegionLeft(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_HEIGHT);
758 Rect offsetRegionTop(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_OFFSET);
759
760 expectBufferColor(offsetRegionLeft, 0, 0, 0, 0);
761 expectBufferColor(offsetRegionTop, 0, 0, 0, 0);
762}
763
764template <typename SourceVariant>
Alec Mouri5a6d8572020-03-23 23:56:15 -0700765void RenderEngineTest::fillBufferCheckers(uint32_t orientationFlag) {
Alec Mouri1089aed2018-10-25 21:33:57 -0700766 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800767 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700768 settings.physicalDisplay = fullscreenRect();
769 // Here logical space is 2x2
770 settings.clip = Rect(2, 2);
Alec Mouri5a6d8572020-03-23 23:56:15 -0700771 settings.orientation = orientationFlag;
Alec Mouri1089aed2018-10-25 21:33:57 -0700772
Sally Qi59a9f502021-10-12 18:53:23 +0000773 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700774
775 renderengine::LayerSettings layerOne;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800776 layerOne.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700777 Rect rectOne(0, 0, 1, 1);
778 layerOne.geometry.boundaries = rectOne.toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800779 SourceVariant::fillColor(layerOne, 1.0f, 0.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700780 layerOne.alpha = 1.0f;
781
782 renderengine::LayerSettings layerTwo;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800783 layerTwo.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700784 Rect rectTwo(0, 1, 1, 2);
785 layerTwo.geometry.boundaries = rectTwo.toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800786 SourceVariant::fillColor(layerTwo, 0.0f, 1.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700787 layerTwo.alpha = 1.0f;
788
789 renderengine::LayerSettings layerThree;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800790 layerThree.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700791 Rect rectThree(1, 0, 2, 1);
792 layerThree.geometry.boundaries = rectThree.toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800793 SourceVariant::fillColor(layerThree, 0.0f, 0.0f, 1.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700794 layerThree.alpha = 1.0f;
795
Sally Qi59a9f502021-10-12 18:53:23 +0000796 layers.push_back(layerOne);
797 layers.push_back(layerTwo);
798 layers.push_back(layerThree);
Alec Mouri1089aed2018-10-25 21:33:57 -0700799
Alec Mouric0aae732021-01-12 13:32:18 -0800800 invokeDraw(settings, layers);
Alec Mouri1089aed2018-10-25 21:33:57 -0700801}
802
803template <typename SourceVariant>
804void RenderEngineTest::fillBufferCheckersRotate0() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700805 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_0);
Alec Mouri1089aed2018-10-25 21:33:57 -0700806 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0,
807 255);
808 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
809 DEFAULT_DISPLAY_HEIGHT / 2),
810 0, 0, 255, 255);
811 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
812 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
813 0, 0, 0, 0);
814 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
815 DEFAULT_DISPLAY_HEIGHT),
816 0, 255, 0, 255);
817}
818
819template <typename SourceVariant>
820void RenderEngineTest::fillBufferCheckersRotate90() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700821 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_90);
Alec Mouri1089aed2018-10-25 21:33:57 -0700822 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 255, 0,
823 255);
824 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
825 DEFAULT_DISPLAY_HEIGHT / 2),
826 255, 0, 0, 255);
827 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
828 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
829 0, 0, 255, 255);
830 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
831 DEFAULT_DISPLAY_HEIGHT),
832 0, 0, 0, 0);
833}
834
835template <typename SourceVariant>
836void RenderEngineTest::fillBufferCheckersRotate180() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700837 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_180);
Alec Mouri1089aed2018-10-25 21:33:57 -0700838 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 0,
839 0);
840 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
841 DEFAULT_DISPLAY_HEIGHT / 2),
842 0, 255, 0, 255);
843 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
844 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
845 255, 0, 0, 255);
846 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
847 DEFAULT_DISPLAY_HEIGHT),
848 0, 0, 255, 255);
849}
850
851template <typename SourceVariant>
852void RenderEngineTest::fillBufferCheckersRotate270() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700853 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_270);
Alec Mouri1089aed2018-10-25 21:33:57 -0700854 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 255,
855 255);
856 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
857 DEFAULT_DISPLAY_HEIGHT / 2),
858 0, 0, 0, 0);
859 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
860 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
861 0, 255, 0, 255);
862 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
863 DEFAULT_DISPLAY_HEIGHT),
864 255, 0, 0, 255);
865}
866
867template <typename SourceVariant>
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800868void RenderEngineTest::fillBufferWithLayerTransform() {
Alec Mouri1089aed2018-10-25 21:33:57 -0700869 renderengine::DisplaySettings settings;
870 settings.physicalDisplay = fullscreenRect();
871 // Here logical space is 2x2
872 settings.clip = Rect(2, 2);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800873 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700874
Sally Qi59a9f502021-10-12 18:53:23 +0000875 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700876
877 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800878 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700879 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
880 // Translate one pixel diagonally
881 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 -0800882 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700883 layer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
884 layer.alpha = 1.0f;
885
Sally Qi59a9f502021-10-12 18:53:23 +0000886 layers.push_back(layer);
Alec Mouri1089aed2018-10-25 21:33:57 -0700887
Alec Mouric0aae732021-01-12 13:32:18 -0800888 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800889}
Alec Mouri1089aed2018-10-25 21:33:57 -0700890
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800891template <typename SourceVariant>
892void RenderEngineTest::fillBufferLayerTransform() {
893 fillBufferWithLayerTransform<SourceVariant>();
Alec Mouri1089aed2018-10-25 21:33:57 -0700894 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 0, 0);
895 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
896 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
897 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
898 255, 0, 0, 255);
899}
900
901template <typename SourceVariant>
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800902void RenderEngineTest::fillBufferWithColorTransform() {
Alec Mouri1089aed2018-10-25 21:33:57 -0700903 renderengine::DisplaySettings settings;
904 settings.physicalDisplay = fullscreenRect();
905 settings.clip = Rect(1, 1);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800906 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700907
Sally Qi59a9f502021-10-12 18:53:23 +0000908 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700909
910 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800911 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700912 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800913 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700914 layer.alpha = 1.0f;
915
916 // construct a fake color matrix
917 // annihilate green and blue channels
KaiChieh Chuang436fc192020-09-07 13:48:42 +0800918 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
Alec Mouri1089aed2018-10-25 21:33:57 -0700919 // set red channel to red + green
920 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
921
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800922 layer.alpha = 1.0f;
923 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
924
Sally Qi59a9f502021-10-12 18:53:23 +0000925 layers.push_back(layer);
Alec Mouri1089aed2018-10-25 21:33:57 -0700926
Alec Mouric0aae732021-01-12 13:32:18 -0800927 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800928}
Alec Mouri1089aed2018-10-25 21:33:57 -0700929
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800930template <typename SourceVariant>
Sally Qi2019fd22021-11-22 10:19:04 -0800931void RenderEngineTest::fillBufferWithColorTransformAndSourceDataspace(
932 const ui::Dataspace sourceDataspace) {
933 renderengine::DisplaySettings settings;
934 settings.physicalDisplay = fullscreenRect();
935 settings.clip = Rect(1, 1);
936 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
937
938 std::vector<renderengine::LayerSettings> layers;
939
940 renderengine::LayerSettings layer;
Sally Qi2019fd22021-11-22 10:19:04 -0800941 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
942 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
Alec Mouric16974e2022-09-13 17:35:48 +0000943 layer.sourceDataspace = sourceDataspace;
Sally Qi2019fd22021-11-22 10:19:04 -0800944 layer.alpha = 1.0f;
945
946 // construct a fake color matrix
947 // annihilate green and blue channels
948 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
949 // set red channel to red + green
950 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
951
952 layer.alpha = 1.0f;
953 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
954
955 layers.push_back(layer);
956
957 invokeDraw(settings, layers);
958}
959
960template <typename SourceVariant>
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800961void RenderEngineTest::fillBufferColorTransform() {
962 fillBufferWithColorTransform<SourceVariant>();
KaiChieh Chuang436fc192020-09-07 13:48:42 +0800963 expectBufferColor(fullscreenRect(), 172, 0, 0, 255, 1);
964}
965
966template <typename SourceVariant>
Sally Qi2019fd22021-11-22 10:19:04 -0800967void RenderEngineTest::fillBufferColorTransformAndSourceDataspace() {
968 unordered_map<ui::Dataspace, ubyte4> dataspaceToColorMap;
Alec Mouric16974e2022-09-13 17:35:48 +0000969 dataspaceToColorMap[ui::Dataspace::V0_BT709] = {77, 0, 0, 255};
970 dataspaceToColorMap[ui::Dataspace::BT2020] = {101, 0, 0, 255};
971 dataspaceToColorMap[ui::Dataspace::ADOBE_RGB] = {75, 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_2 |
974 ui::Dataspace::RANGE_FULL);
Alec Mouric16974e2022-09-13 17:35:48 +0000975 dataspaceToColorMap[customizedDataspace] = {61, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -0800976 for (const auto& [sourceDataspace, color] : dataspaceToColorMap) {
977 fillBufferWithColorTransformAndSourceDataspace<SourceVariant>(sourceDataspace);
978 expectBufferColor(fullscreenRect(), color.r, color.g, color.b, color.a, 1);
979 }
980}
981
982template <typename SourceVariant>
983void RenderEngineTest::fillBufferWithColorTransformAndOutputDataspace(
984 const ui::Dataspace outputDataspace) {
985 renderengine::DisplaySettings settings;
986 settings.physicalDisplay = fullscreenRect();
987 settings.clip = Rect(1, 1);
988 settings.outputDataspace = outputDataspace;
989
990 std::vector<renderengine::LayerSettings> layers;
991
992 renderengine::LayerSettings layer;
993 layer.sourceDataspace = ui::Dataspace::V0_SCRGB_LINEAR;
994 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
995 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
996 layer.alpha = 1.0f;
997
998 // construct a fake color matrix
999 // annihilate green and blue channels
1000 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
1001 // set red channel to red + green
1002 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
1003
1004 layer.alpha = 1.0f;
1005 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1006
1007 layers.push_back(layer);
1008
1009 invokeDraw(settings, layers);
1010}
1011
1012template <typename SourceVariant>
1013void RenderEngineTest::fillBufferColorTransformAndOutputDataspace() {
1014 unordered_map<ui::Dataspace, ubyte4> dataspaceToColorMap;
Alec Mouric16974e2022-09-13 17:35:48 +00001015 dataspaceToColorMap[ui::Dataspace::V0_BT709] = {198, 0, 0, 255};
1016 dataspaceToColorMap[ui::Dataspace::BT2020] = {187, 0, 0, 255};
1017 dataspaceToColorMap[ui::Dataspace::ADOBE_RGB] = {192, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -08001018 ui::Dataspace customizedDataspace = static_cast<ui::Dataspace>(
1019 ui::Dataspace::STANDARD_BT709 | ui::Dataspace::TRANSFER_GAMMA2_6 |
1020 ui::Dataspace::RANGE_FULL);
Alec Mouric16974e2022-09-13 17:35:48 +00001021 dataspaceToColorMap[customizedDataspace] = {205, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -08001022 for (const auto& [outputDataspace, color] : dataspaceToColorMap) {
1023 fillBufferWithColorTransformAndOutputDataspace<SourceVariant>(outputDataspace);
1024 expectBufferColor(fullscreenRect(), color.r, color.g, color.b, color.a, 1);
1025 }
1026}
1027
1028template <typename SourceVariant>
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001029void RenderEngineTest::fillBufferWithColorTransformZeroLayerAlpha() {
1030 renderengine::DisplaySettings settings;
1031 settings.physicalDisplay = fullscreenRect();
1032 settings.clip = Rect(1, 1);
1033
Sally Qi59a9f502021-10-12 18:53:23 +00001034 std::vector<renderengine::LayerSettings> layers;
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001035
1036 renderengine::LayerSettings layer;
1037 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1038 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
1039 layer.alpha = 0;
1040
1041 // construct a fake color matrix
1042 // simple inverse color
1043 settings.colorTransform = mat4(-1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 1, 1, 1, 1);
1044
1045 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1046
Sally Qi59a9f502021-10-12 18:53:23 +00001047 layers.push_back(layer);
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001048
Alec Mouric0aae732021-01-12 13:32:18 -08001049 invokeDraw(settings, layers);
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001050}
1051
1052template <typename SourceVariant>
1053void RenderEngineTest::fillBufferColorTransformZeroLayerAlpha() {
1054 fillBufferWithColorTransformZeroLayerAlpha<SourceVariant>();
1055 expectBufferColor(fullscreenRect(), 0, 0, 0, 0);
1056}
1057
1058template <typename SourceVariant>
Alec Mouri7c94edb2018-12-03 21:23:26 -08001059void RenderEngineTest::fillRedBufferWithRoundedCorners() {
1060 renderengine::DisplaySettings settings;
1061 settings.physicalDisplay = fullscreenRect();
1062 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001063 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri7c94edb2018-12-03 21:23:26 -08001064
Sally Qi59a9f502021-10-12 18:53:23 +00001065 std::vector<renderengine::LayerSettings> layers;
Alec Mouri7c94edb2018-12-03 21:23:26 -08001066
1067 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001068 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri7c94edb2018-12-03 21:23:26 -08001069 layer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07001070 layer.geometry.roundedCornersRadius = {5.0f, 5.0f};
Alec Mouri7c94edb2018-12-03 21:23:26 -08001071 layer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
1072 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
1073 layer.alpha = 1.0f;
1074
Sally Qi59a9f502021-10-12 18:53:23 +00001075 layers.push_back(layer);
Alec Mouri7c94edb2018-12-03 21:23:26 -08001076
Alec Mouric0aae732021-01-12 13:32:18 -08001077 invokeDraw(settings, layers);
Alec Mouri7c94edb2018-12-03 21:23:26 -08001078}
1079
1080template <typename SourceVariant>
1081void RenderEngineTest::fillBufferWithRoundedCorners() {
1082 fillRedBufferWithRoundedCorners<SourceVariant>();
1083 // Corners should be ignored...
1084 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 0);
1085 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, 0, DEFAULT_DISPLAY_WIDTH, 1), 0, 0, 0, 0);
1086 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT - 1, 1, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
1087 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1,
1088 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1089 0, 0, 0, 0);
1090 // ...And the non-rounded portion should be red.
1091 // Other pixels may be anti-aliased, so let's not check those.
1092 expectBufferColor(Rect(5, 5, DEFAULT_DISPLAY_WIDTH - 5, DEFAULT_DISPLAY_HEIGHT - 5), 255, 0, 0,
1093 255);
1094}
1095
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001096template <typename SourceVariant>
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001097void RenderEngineTest::fillBufferAndBlurBackground() {
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001098 auto blurRadius = 50;
1099 auto center = DEFAULT_DISPLAY_WIDTH / 2;
1100
1101 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001102 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001103 settings.physicalDisplay = fullscreenRect();
1104 settings.clip = fullscreenRect();
1105
Sally Qi59a9f502021-10-12 18:53:23 +00001106 std::vector<renderengine::LayerSettings> layers;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001107
1108 renderengine::LayerSettings backgroundLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001109 backgroundLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001110 backgroundLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1111 SourceVariant::fillColor(backgroundLayer, 0.0f, 1.0f, 0.0f, this);
1112 backgroundLayer.alpha = 1.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001113 layers.emplace_back(backgroundLayer);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001114
1115 renderengine::LayerSettings leftLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001116 leftLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001117 leftLayer.geometry.boundaries =
1118 Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT).toFloatRect();
1119 SourceVariant::fillColor(leftLayer, 1.0f, 0.0f, 0.0f, this);
1120 leftLayer.alpha = 1.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001121 layers.emplace_back(leftLayer);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001122
1123 renderengine::LayerSettings blurLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001124 blurLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001125 blurLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1126 blurLayer.backgroundBlurRadius = blurRadius;
Derek Sollenbergerecb21462021-01-29 16:53:49 -05001127 SourceVariant::fillColor(blurLayer, 0.0f, 0.0f, 1.0f, this);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001128 blurLayer.alpha = 0;
Sally Qi59a9f502021-10-12 18:53:23 +00001129 layers.emplace_back(blurLayer);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001130
Alec Mouric0aae732021-01-12 13:32:18 -08001131 invokeDraw(settings, layers);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001132
Derek Sollenbergerecb21462021-01-29 16:53:49 -05001133 // solid color
1134 expectBufferColor(Rect(0, 0, 1, 1), 255, 0, 0, 255, 0 /* tolerance */);
1135
Derek Sollenbergerb3998372021-02-16 15:16:56 -05001136 if (mRE->supportsBackgroundBlur()) {
1137 // blurred color (downsampling should result in the center color being close to 128)
1138 expectBufferColor(Rect(center - 1, center - 5, center + 1, center + 5), 128, 128, 0, 255,
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001139 50 /* tolerance */);
Derek Sollenbergerb3998372021-02-16 15:16:56 -05001140 }
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001141}
1142
1143template <typename SourceVariant>
Alec Mourie8489fd2021-04-29 16:08:56 -07001144void RenderEngineTest::fillSmallLayerAndBlurBackground() {
1145 auto blurRadius = 50;
1146 renderengine::DisplaySettings settings;
1147 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1148 settings.physicalDisplay = fullscreenRect();
1149 settings.clip = fullscreenRect();
1150
Sally Qi59a9f502021-10-12 18:53:23 +00001151 std::vector<renderengine::LayerSettings> layers;
Alec Mourie8489fd2021-04-29 16:08:56 -07001152
1153 renderengine::LayerSettings backgroundLayer;
1154 backgroundLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1155 backgroundLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1156 SourceVariant::fillColor(backgroundLayer, 1.0f, 0.0f, 0.0f, this);
1157 backgroundLayer.alpha = 1.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001158 layers.push_back(backgroundLayer);
Alec Mourie8489fd2021-04-29 16:08:56 -07001159
1160 renderengine::LayerSettings blurLayer;
1161 blurLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1162 blurLayer.geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f);
1163 blurLayer.backgroundBlurRadius = blurRadius;
1164 SourceVariant::fillColor(blurLayer, 0.0f, 0.0f, 1.0f, this);
1165 blurLayer.alpha = 0;
Sally Qi59a9f502021-10-12 18:53:23 +00001166 layers.push_back(blurLayer);
Alec Mourie8489fd2021-04-29 16:08:56 -07001167
1168 invokeDraw(settings, layers);
1169
1170 // Give a generous tolerance - the blur rectangle is very small and this test is
1171 // mainly concerned with ensuring that there's no device failure.
1172 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT), 255, 0, 0, 255,
1173 40 /* tolerance */);
1174}
1175
1176template <typename SourceVariant>
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001177void RenderEngineTest::overlayCorners() {
1178 renderengine::DisplaySettings settings;
1179 settings.physicalDisplay = fullscreenRect();
1180 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001181 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001182
Sally Qi59a9f502021-10-12 18:53:23 +00001183 std::vector<renderengine::LayerSettings> layersFirst;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001184
1185 renderengine::LayerSettings layerOne;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001186 layerOne.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001187 layerOne.geometry.boundaries =
1188 FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH / 3.0, DEFAULT_DISPLAY_HEIGHT / 3.0);
1189 SourceVariant::fillColor(layerOne, 1.0f, 0.0f, 0.0f, this);
1190 layerOne.alpha = 0.2;
1191
Sally Qi59a9f502021-10-12 18:53:23 +00001192 layersFirst.push_back(layerOne);
Alec Mouric0aae732021-01-12 13:32:18 -08001193 invokeDraw(settings, layersFirst);
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001194 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3), 51, 0, 0, 51);
1195 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3 + 1, DEFAULT_DISPLAY_HEIGHT / 3 + 1,
1196 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1197 0, 0, 0, 0);
1198
Sally Qi59a9f502021-10-12 18:53:23 +00001199 std::vector<renderengine::LayerSettings> layersSecond;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001200 renderengine::LayerSettings layerTwo;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001201 layerTwo.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001202 layerTwo.geometry.boundaries =
1203 FloatRect(DEFAULT_DISPLAY_WIDTH / 3.0, DEFAULT_DISPLAY_HEIGHT / 3.0,
1204 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT);
1205 SourceVariant::fillColor(layerTwo, 0.0f, 1.0f, 0.0f, this);
1206 layerTwo.alpha = 1.0f;
1207
Sally Qi59a9f502021-10-12 18:53:23 +00001208 layersSecond.push_back(layerTwo);
Alec Mouric0aae732021-01-12 13:32:18 -08001209 invokeDraw(settings, layersSecond);
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001210
1211 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3), 0, 0, 0, 0);
1212 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3 + 1, DEFAULT_DISPLAY_HEIGHT / 3 + 1,
1213 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1214 0, 255, 0, 255);
1215}
1216
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001217void RenderEngineTest::fillRedBufferTextureTransform() {
1218 renderengine::DisplaySettings settings;
1219 settings.physicalDisplay = fullscreenRect();
1220 settings.clip = Rect(1, 1);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001221 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001222
Sally Qi59a9f502021-10-12 18:53:23 +00001223 std::vector<renderengine::LayerSettings> layers;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001224
1225 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001226 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001227 // Here will allocate a checker board texture, but transform texture
1228 // coordinates so that only the upper left is applied.
Alec Mouria90a5702021-04-16 16:36:21 +00001229 const auto buf = allocateSourceBuffer(2, 2);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001230
1231 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00001232 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1233 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001234 // Red top left, Green top right, Blue bottom left, Black bottom right
1235 pixels[0] = 255;
1236 pixels[1] = 0;
1237 pixels[2] = 0;
1238 pixels[3] = 255;
1239 pixels[4] = 0;
1240 pixels[5] = 255;
1241 pixels[6] = 0;
1242 pixels[7] = 255;
1243 pixels[8] = 0;
1244 pixels[9] = 0;
1245 pixels[10] = 255;
1246 pixels[11] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00001247 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001248
1249 layer.source.buffer.buffer = buf;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001250 // Transform coordinates to only be inside the red quadrant.
Alec Mouri4049b532021-10-15 20:59:33 -07001251 layer.source.buffer.textureTransform = mat4::scale(vec4(0.2f, 0.2f, 1.f, 1.f));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001252 layer.alpha = 1.0f;
1253 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1254
Sally Qi59a9f502021-10-12 18:53:23 +00001255 layers.push_back(layer);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001256
Alec Mouric0aae732021-01-12 13:32:18 -08001257 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001258}
1259
1260void RenderEngineTest::fillBufferTextureTransform() {
1261 fillRedBufferTextureTransform();
1262 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
1263}
1264
1265void RenderEngineTest::fillRedBufferWithPremultiplyAlpha() {
1266 renderengine::DisplaySettings settings;
1267 settings.physicalDisplay = fullscreenRect();
1268 // Here logical space is 1x1
1269 settings.clip = Rect(1, 1);
1270
Sally Qi59a9f502021-10-12 18:53:23 +00001271 std::vector<renderengine::LayerSettings> layers;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001272
1273 renderengine::LayerSettings layer;
Alec Mouria90a5702021-04-16 16:36:21 +00001274 const auto buf = allocateSourceBuffer(1, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001275
1276 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00001277 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1278 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001279 pixels[0] = 255;
1280 pixels[1] = 0;
1281 pixels[2] = 0;
1282 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00001283 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001284
1285 layer.source.buffer.buffer = buf;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001286 layer.source.buffer.usePremultipliedAlpha = true;
1287 layer.alpha = 0.5f;
1288 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1289
Sally Qi59a9f502021-10-12 18:53:23 +00001290 layers.push_back(layer);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001291
Alec Mouric0aae732021-01-12 13:32:18 -08001292 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001293}
1294
1295void RenderEngineTest::fillBufferWithPremultiplyAlpha() {
1296 fillRedBufferWithPremultiplyAlpha();
1297 expectBufferColor(fullscreenRect(), 128, 0, 0, 128);
1298}
1299
1300void RenderEngineTest::fillRedBufferWithoutPremultiplyAlpha() {
1301 renderengine::DisplaySettings settings;
1302 settings.physicalDisplay = fullscreenRect();
1303 // Here logical space is 1x1
1304 settings.clip = Rect(1, 1);
1305
Sally Qi59a9f502021-10-12 18:53:23 +00001306 std::vector<renderengine::LayerSettings> layers;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001307
1308 renderengine::LayerSettings layer;
Alec Mouria90a5702021-04-16 16:36:21 +00001309 const auto buf = allocateSourceBuffer(1, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001310
1311 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00001312 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1313 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001314 pixels[0] = 255;
1315 pixels[1] = 0;
1316 pixels[2] = 0;
1317 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00001318 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001319
1320 layer.source.buffer.buffer = buf;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001321 layer.source.buffer.usePremultipliedAlpha = false;
1322 layer.alpha = 0.5f;
1323 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1324
Sally Qi59a9f502021-10-12 18:53:23 +00001325 layers.push_back(layer);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001326
Alec Mouric0aae732021-01-12 13:32:18 -08001327 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001328}
1329
1330void RenderEngineTest::fillBufferWithoutPremultiplyAlpha() {
1331 fillRedBufferWithoutPremultiplyAlpha();
wukui16f3c0bb2020-08-05 20:35:29 +08001332 expectBufferColor(fullscreenRect(), 128, 0, 0, 128, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001333}
1334
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001335template <typename SourceVariant>
1336void RenderEngineTest::drawShadow(const renderengine::LayerSettings& castingLayer,
Vishnu Naird9e4f462023-10-06 04:05:45 +00001337 const ShadowSettings& shadow, const ubyte4& casterColor,
1338 const ubyte4& backgroundColor) {
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001339 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001340 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001341 settings.physicalDisplay = fullscreenRect();
1342 settings.clip = fullscreenRect();
1343
Sally Qi59a9f502021-10-12 18:53:23 +00001344 std::vector<renderengine::LayerSettings> layers;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001345
1346 // add background layer
1347 renderengine::LayerSettings bgLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001348 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001349 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1350 ColorSourceVariant::fillColor(bgLayer, backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1351 backgroundColor.b / 255.0f, this);
1352 bgLayer.alpha = backgroundColor.a / 255.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001353 layers.push_back(bgLayer);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001354
1355 // add shadow layer
1356 renderengine::LayerSettings shadowLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001357 shadowLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001358 shadowLayer.geometry.boundaries = castingLayer.geometry.boundaries;
1359 shadowLayer.alpha = castingLayer.alpha;
1360 shadowLayer.shadow = shadow;
Sally Qi59a9f502021-10-12 18:53:23 +00001361 layers.push_back(shadowLayer);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001362
1363 // add layer casting the shadow
1364 renderengine::LayerSettings layer = castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001365 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001366 SourceVariant::fillColor(layer, casterColor.r / 255.0f, casterColor.g / 255.0f,
1367 casterColor.b / 255.0f, this);
Sally Qi59a9f502021-10-12 18:53:23 +00001368 layers.push_back(layer);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001369
Alec Mouric0aae732021-01-12 13:32:18 -08001370 invokeDraw(settings, layers);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001371}
1372
Alec Mouribd17b3b2020-12-17 11:08:30 -08001373void RenderEngineTest::drawShadowWithoutCaster(const FloatRect& castingBounds,
Vishnu Naird9e4f462023-10-06 04:05:45 +00001374 const ShadowSettings& shadow,
Alec Mouribd17b3b2020-12-17 11:08:30 -08001375 const ubyte4& backgroundColor) {
1376 renderengine::DisplaySettings settings;
1377 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1378 settings.physicalDisplay = fullscreenRect();
1379 settings.clip = fullscreenRect();
1380
Sally Qi59a9f502021-10-12 18:53:23 +00001381 std::vector<renderengine::LayerSettings> layers;
Alec Mouribd17b3b2020-12-17 11:08:30 -08001382
1383 // add background layer
1384 renderengine::LayerSettings bgLayer;
1385 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1386 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1387 ColorSourceVariant::fillColor(bgLayer, backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1388 backgroundColor.b / 255.0f, this);
1389 bgLayer.alpha = backgroundColor.a / 255.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001390 layers.push_back(bgLayer);
Alec Mouribd17b3b2020-12-17 11:08:30 -08001391
1392 // add shadow layer
1393 renderengine::LayerSettings shadowLayer;
1394 shadowLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1395 shadowLayer.geometry.boundaries = castingBounds;
Derek Sollenbergerc31985e2021-05-18 16:38:17 -04001396 shadowLayer.skipContentDraw = true;
Alec Mouribd17b3b2020-12-17 11:08:30 -08001397 shadowLayer.alpha = 1.0f;
1398 ColorSourceVariant::fillColor(shadowLayer, 0, 0, 0, this);
1399 shadowLayer.shadow = shadow;
Sally Qi59a9f502021-10-12 18:53:23 +00001400 layers.push_back(shadowLayer);
Alec Mouribd17b3b2020-12-17 11:08:30 -08001401
Alec Mouric0aae732021-01-12 13:32:18 -08001402 invokeDraw(settings, layers);
Alec Mouribd17b3b2020-12-17 11:08:30 -08001403}
1404
Alec Mouri5a493722022-01-26 16:43:02 -08001405void RenderEngineTest::tonemap(ui::Dataspace sourceDataspace, std::function<vec3(vec3)> eotf,
1406 std::function<vec3(vec3, float)> scaleOotf) {
1407 constexpr int32_t kGreyLevels = 256;
1408
1409 const auto rect = Rect(0, 0, kGreyLevels, 1);
1410
1411 constexpr float kMaxLuminance = 750.f;
1412 constexpr float kCurrentLuminanceNits = 500.f;
1413 const renderengine::DisplaySettings display{
1414 .physicalDisplay = rect,
1415 .clip = rect,
1416 .maxLuminance = kMaxLuminance,
1417 .currentLuminanceNits = kCurrentLuminanceNits,
1418 .outputDataspace = ui::Dataspace::DISPLAY_P3,
1419 };
1420
1421 auto buf = std::make_shared<
1422 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07001423 ExternalTexture>(sp<GraphicBuffer>::make(kGreyLevels, 1,
1424 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1425 GRALLOC_USAGE_SW_READ_OFTEN |
1426 GRALLOC_USAGE_SW_WRITE_OFTEN |
1427 GRALLOC_USAGE_HW_RENDER |
1428 GRALLOC_USAGE_HW_TEXTURE,
1429 "input"),
Alec Mouri5a493722022-01-26 16:43:02 -08001430 *mRE,
1431 renderengine::impl::ExternalTexture::Usage::READABLE |
1432 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
1433 ASSERT_EQ(0, buf->getBuffer()->initCheck());
1434 {
1435 uint8_t* pixels;
1436 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1437 reinterpret_cast<void**>(&pixels));
1438
1439 uint8_t color = 0;
1440 for (int32_t j = 0; j < buf->getBuffer()->getHeight(); j++) {
1441 uint8_t* dest = pixels + (buf->getBuffer()->getStride() * j * 4);
1442 for (int32_t i = 0; i < buf->getBuffer()->getWidth(); i++) {
1443 dest[0] = color;
1444 dest[1] = color;
1445 dest[2] = color;
1446 dest[3] = 255;
1447 color++;
1448 dest += 4;
1449 }
1450 }
1451 buf->getBuffer()->unlock();
1452 }
1453
1454 mBuffer = std::make_shared<
1455 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07001456 ExternalTexture>(sp<GraphicBuffer>::make(kGreyLevels, 1,
1457 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1458 GRALLOC_USAGE_SW_READ_OFTEN |
1459 GRALLOC_USAGE_SW_WRITE_OFTEN |
1460 GRALLOC_USAGE_HW_RENDER |
1461 GRALLOC_USAGE_HW_TEXTURE,
1462 "output"),
Alec Mouri5a493722022-01-26 16:43:02 -08001463 *mRE,
1464 renderengine::impl::ExternalTexture::Usage::READABLE |
1465 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
1466 ASSERT_EQ(0, mBuffer->getBuffer()->initCheck());
1467
1468 const renderengine::LayerSettings layer{.geometry.boundaries = rect.toFloatRect(),
1469 .source =
1470 renderengine::PixelSource{
1471 .buffer =
1472 renderengine::Buffer{
1473 .buffer =
1474 std::move(buf),
1475 .usePremultipliedAlpha =
1476 true,
1477 },
1478 },
1479 .alpha = 1.0f,
1480 .sourceDataspace = sourceDataspace};
1481
1482 std::vector<renderengine::LayerSettings> layers{layer};
1483 invokeDraw(display, layers);
1484
1485 ColorSpace displayP3 = ColorSpace::DisplayP3();
1486 ColorSpace bt2020 = ColorSpace::BT2020();
1487
1488 tonemap::Metadata metadata{.displayMaxLuminance = 750.0f};
1489
1490 auto generator = [=](Point location) {
1491 const double normColor = static_cast<double>(location.x) / (kGreyLevels - 1);
1492 const vec3 rgb = vec3(normColor, normColor, normColor);
1493
1494 const vec3 linearRGB = eotf(rgb);
1495
1496 const vec3 xyz = bt2020.getRGBtoXYZ() * linearRGB;
1497
1498 const vec3 scaledXYZ = scaleOotf(xyz, kCurrentLuminanceNits);
Alec Mouri196b0f22022-03-04 22:13:48 +00001499 const auto gains =
Alec Mouri5a493722022-01-26 16:43:02 -08001500 tonemap::getToneMapper()
1501 ->lookupTonemapGain(static_cast<aidl::android::hardware::graphics::common::
1502 Dataspace>(sourceDataspace),
1503 static_cast<aidl::android::hardware::graphics::common::
1504 Dataspace>(
1505 ui::Dataspace::DISPLAY_P3),
Alec Mouri196b0f22022-03-04 22:13:48 +00001506 {tonemap::
1507 Color{.linearRGB =
1508 scaleOotf(linearRGB,
1509 kCurrentLuminanceNits),
1510 .xyz = scaledXYZ}},
Alec Mouri5a493722022-01-26 16:43:02 -08001511 metadata);
Alec Mouri196b0f22022-03-04 22:13:48 +00001512 EXPECT_EQ(1, gains.size());
1513 const double gain = gains.front();
Alec Mouri5a493722022-01-26 16:43:02 -08001514 const vec3 normalizedXYZ = scaledXYZ * gain / metadata.displayMaxLuminance;
1515
1516 const vec3 targetRGB = OETF_sRGB(displayP3.getXYZtoRGB() * normalizedXYZ) * 255;
1517 return ubyte4(static_cast<uint8_t>(targetRGB.r), static_cast<uint8_t>(targetRGB.g),
1518 static_cast<uint8_t>(targetRGB.b), 255);
1519 };
1520
1521 expectBufferColor(Rect(kGreyLevels, 1), generator, 2);
1522}
1523
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001524INSTANTIATE_TEST_SUITE_P(PerRenderEngineType, RenderEngineTest,
Alec Mouric16974e2022-09-13 17:35:48 +00001525 testing::Values(std::make_shared<SkiaGLESRenderEngineFactory>(),
Alec Mouri47bcb072023-08-15 02:02:49 +00001526 std::make_shared<SkiaVkRenderEngineFactory>()));
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001527
1528TEST_P(RenderEngineTest, drawLayers_noLayersToDraw) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001529 if (!GetParam()->typeSupported()) {
1530 GTEST_SKIP();
1531 }
Alec Mouric0aae732021-01-12 13:32:18 -08001532 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001533 drawEmptyLayers();
1534}
1535
Sally Qi1fed86e2022-06-23 15:33:52 -07001536TEST_P(RenderEngineTest, drawLayers_fillRedBufferAndEmptyBuffer) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001537 if (!GetParam()->typeSupported()) {
1538 GTEST_SKIP();
1539 }
Sally Qi1fed86e2022-06-23 15:33:52 -07001540 initializeRenderEngine();
1541 renderengine::DisplaySettings settings;
1542 settings.physicalDisplay = fullscreenRect();
1543 settings.clip = fullscreenRect();
1544 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1545
1546 // add a red layer
1547 renderengine::LayerSettings layerOne{
1548 .geometry.boundaries = fullscreenRect().toFloatRect(),
1549 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
1550 .alpha = 1.f,
1551 };
1552
1553 std::vector<renderengine::LayerSettings> layersFirst{layerOne};
1554 invokeDraw(settings, layersFirst);
1555 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
1556
1557 // re-draw with an empty layer above it, and we get a transparent black one
1558 std::vector<renderengine::LayerSettings> layersSecond;
1559 invokeDraw(settings, layersSecond);
1560 expectBufferColor(fullscreenRect(), 0, 0, 0, 0);
1561}
1562
Ana Krulec07b98df2021-01-07 14:38:40 -08001563TEST_P(RenderEngineTest, drawLayers_withoutBuffers_withColorTransform) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001564 if (!GetParam()->typeSupported()) {
1565 GTEST_SKIP();
1566 }
Alec Mouria90a5702021-04-16 16:36:21 +00001567 initializeRenderEngine();
Ana Krulec07b98df2021-01-07 14:38:40 -08001568
1569 renderengine::DisplaySettings settings;
1570 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1571 settings.physicalDisplay = fullscreenRect();
1572 settings.clip = fullscreenRect();
1573
1574 // 255, 255, 255, 255 is full opaque white.
Alec Mouri4049b532021-10-15 20:59:33 -07001575 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
1576 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Ana Krulec07b98df2021-01-07 14:38:40 -08001577 // Create layer with given color.
1578 renderengine::LayerSettings bgLayer;
1579 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1580 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1581 bgLayer.source.solidColor = half3(backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1582 backgroundColor.b / 255.0f);
1583 bgLayer.alpha = backgroundColor.a / 255.0f;
1584 // Transform the red color.
1585 bgLayer.colorTransform = mat4(-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
1586
Sally Qi59a9f502021-10-12 18:53:23 +00001587 std::vector<renderengine::LayerSettings> layers;
1588 layers.push_back(bgLayer);
Ana Krulec07b98df2021-01-07 14:38:40 -08001589
Alec Mouric0aae732021-01-12 13:32:18 -08001590 invokeDraw(settings, layers);
Ana Krulec07b98df2021-01-07 14:38:40 -08001591
1592 // Expect to see full opaque pixel (with inverted red from the transform).
Alec Mouric0aae732021-01-12 13:32:18 -08001593 expectBufferColor(Rect(0, 0, 10, 10), 0.f, backgroundColor.g, backgroundColor.b,
Ana Krulec07b98df2021-01-07 14:38:40 -08001594 backgroundColor.a);
1595}
1596
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001597TEST_P(RenderEngineTest, drawLayers_nullOutputBuffer) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001598 if (!GetParam()->typeSupported()) {
1599 GTEST_SKIP();
1600 }
Alec Mouric0aae732021-01-12 13:32:18 -08001601 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001602
Alec Mourid43ccab2019-03-13 12:23:45 -07001603 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001604 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Sally Qi59a9f502021-10-12 18:53:23 +00001605 std::vector<renderengine::LayerSettings> layers;
Alec Mourid43ccab2019-03-13 12:23:45 -07001606 renderengine::LayerSettings layer;
1607 layer.geometry.boundaries = fullscreenRect().toFloatRect();
1608 BufferSourceVariant<ForceOpaqueBufferVariant>::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
Sally Qi59a9f502021-10-12 18:53:23 +00001609 layers.push_back(layer);
Alec Mourif29700f2023-08-17 21:53:31 +00001610 ftl::Future<FenceResult> future = mRE->drawLayers(settings, layers, nullptr, base::unique_fd());
Alec Mourid43ccab2019-03-13 12:23:45 -07001611
Patrick Williams2e9748f2022-08-09 22:48:18 +00001612 ASSERT_TRUE(future.valid());
1613 auto result = future.get();
1614 ASSERT_FALSE(result.ok());
1615 ASSERT_EQ(BAD_VALUE, result.error());
Alec Mourid43ccab2019-03-13 12:23:45 -07001616}
1617
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001618TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001619 if (!GetParam()->typeSupported()) {
1620 GTEST_SKIP();
1621 }
Alec Mouric0aae732021-01-12 13:32:18 -08001622 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001623 fillRedBuffer<ColorSourceVariant>();
1624}
1625
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001626TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001627 if (!GetParam()->typeSupported()) {
1628 GTEST_SKIP();
1629 }
Alec Mouric0aae732021-01-12 13:32:18 -08001630 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001631 fillGreenBuffer<ColorSourceVariant>();
1632}
1633
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001634TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001635 if (!GetParam()->typeSupported()) {
1636 GTEST_SKIP();
1637 }
Alec Mouric0aae732021-01-12 13:32:18 -08001638 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001639 fillBlueBuffer<ColorSourceVariant>();
1640}
1641
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001642TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001643 if (!GetParam()->typeSupported()) {
1644 GTEST_SKIP();
1645 }
Alec Mouric0aae732021-01-12 13:32:18 -08001646 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001647 fillRedTransparentBuffer<ColorSourceVariant>();
1648}
1649
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001650TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001651 if (!GetParam()->typeSupported()) {
1652 GTEST_SKIP();
1653 }
Alec Mouric0aae732021-01-12 13:32:18 -08001654 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001655 fillBufferPhysicalOffset<ColorSourceVariant>();
1656}
1657
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001658TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001659 if (!GetParam()->typeSupported()) {
1660 GTEST_SKIP();
1661 }
Alec Mouric0aae732021-01-12 13:32:18 -08001662 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001663 fillBufferCheckersRotate0<ColorSourceVariant>();
1664}
1665
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001666TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001667 if (!GetParam()->typeSupported()) {
1668 GTEST_SKIP();
1669 }
Alec Mouric0aae732021-01-12 13:32:18 -08001670 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001671 fillBufferCheckersRotate90<ColorSourceVariant>();
1672}
1673
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001674TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001675 if (!GetParam()->typeSupported()) {
1676 GTEST_SKIP();
1677 }
Alec Mouric0aae732021-01-12 13:32:18 -08001678 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001679 fillBufferCheckersRotate180<ColorSourceVariant>();
1680}
1681
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001682TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001683 if (!GetParam()->typeSupported()) {
1684 GTEST_SKIP();
1685 }
Alec Mouric0aae732021-01-12 13:32:18 -08001686 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001687 fillBufferCheckersRotate270<ColorSourceVariant>();
1688}
1689
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001690TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001691 if (!GetParam()->typeSupported()) {
1692 GTEST_SKIP();
1693 }
Alec Mouric0aae732021-01-12 13:32:18 -08001694 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001695 fillBufferLayerTransform<ColorSourceVariant>();
1696}
1697
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001698TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001699 if (!GetParam()->typeSupported()) {
1700 GTEST_SKIP();
1701 }
Alec Mouric0aae732021-01-12 13:32:18 -08001702 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08001703 fillBufferColorTransform<ColorSourceVariant>();
1704}
1705
Sally Qi2019fd22021-11-22 10:19:04 -08001706TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_sourceDataspace) {
1707 const auto& renderEngineFactory = GetParam();
1708 // skip for non color management
Alec Mouri47bcb072023-08-15 02:02:49 +00001709 if (!renderEngineFactory->typeSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001710 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001711 }
1712
1713 initializeRenderEngine();
1714 fillBufferColorTransformAndSourceDataspace<ColorSourceVariant>();
1715}
1716
1717TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_outputDataspace) {
1718 const auto& renderEngineFactory = GetParam();
1719 // skip for non color management
Alec Mouri47bcb072023-08-15 02:02:49 +00001720 if (!renderEngineFactory->typeSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001721 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001722 }
1723
1724 initializeRenderEngine();
1725 fillBufferColorTransformAndOutputDataspace<ColorSourceVariant>();
1726}
1727
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001728TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001729 if (!GetParam()->typeSupported()) {
1730 GTEST_SKIP();
1731 }
Alec Mouric0aae732021-01-12 13:32:18 -08001732 initializeRenderEngine();
Alec Mouri7c94edb2018-12-03 21:23:26 -08001733 fillBufferWithRoundedCorners<ColorSourceVariant>();
1734}
1735
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001736TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001737 if (!GetParam()->typeSupported()) {
1738 GTEST_SKIP();
1739 }
Alec Mouric0aae732021-01-12 13:32:18 -08001740 initializeRenderEngine();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001741 fillBufferColorTransformZeroLayerAlpha<ColorSourceVariant>();
1742}
1743
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001744TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001745 if (!GetParam()->typeSupported()) {
1746 GTEST_SKIP();
1747 }
Alec Mouric0aae732021-01-12 13:32:18 -08001748 initializeRenderEngine();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001749 fillBufferAndBlurBackground<ColorSourceVariant>();
1750}
1751
Alec Mourie8489fd2021-04-29 16:08:56 -07001752TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001753 if (!GetParam()->typeSupported()) {
1754 GTEST_SKIP();
1755 }
Alec Mourie8489fd2021-04-29 16:08:56 -07001756 initializeRenderEngine();
1757 fillSmallLayerAndBlurBackground<ColorSourceVariant>();
1758}
1759
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001760TEST_P(RenderEngineTest, drawLayers_overlayCorners_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001761 if (!GetParam()->typeSupported()) {
1762 GTEST_SKIP();
1763 }
Alec Mouric0aae732021-01-12 13:32:18 -08001764 initializeRenderEngine();
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001765 overlayCorners<ColorSourceVariant>();
1766}
1767
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001768TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001769 if (!GetParam()->typeSupported()) {
1770 GTEST_SKIP();
1771 }
Alec Mouric0aae732021-01-12 13:32:18 -08001772 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001773 fillRedBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1774}
1775
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001776TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001777 if (!GetParam()->typeSupported()) {
1778 GTEST_SKIP();
1779 }
Alec Mouric0aae732021-01-12 13:32:18 -08001780 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001781 fillGreenBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1782}
1783
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001784TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001785 if (!GetParam()->typeSupported()) {
1786 GTEST_SKIP();
1787 }
Alec Mouric0aae732021-01-12 13:32:18 -08001788 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001789 fillBlueBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1790}
1791
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001792TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001793 if (!GetParam()->typeSupported()) {
1794 GTEST_SKIP();
1795 }
Alec Mouric0aae732021-01-12 13:32:18 -08001796 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001797 fillRedTransparentBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1798}
1799
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001800TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001801 if (!GetParam()->typeSupported()) {
1802 GTEST_SKIP();
1803 }
Alec Mouric0aae732021-01-12 13:32:18 -08001804 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001805 fillBufferPhysicalOffset<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1806}
1807
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001808TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001809 if (!GetParam()->typeSupported()) {
1810 GTEST_SKIP();
1811 }
Alec Mouric0aae732021-01-12 13:32:18 -08001812 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001813 fillBufferCheckersRotate0<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1814}
1815
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001816TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001817 if (!GetParam()->typeSupported()) {
1818 GTEST_SKIP();
1819 }
Alec Mouric0aae732021-01-12 13:32:18 -08001820 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001821 fillBufferCheckersRotate90<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1822}
1823
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001824TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001825 if (!GetParam()->typeSupported()) {
1826 GTEST_SKIP();
1827 }
Alec Mouric0aae732021-01-12 13:32:18 -08001828 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001829 fillBufferCheckersRotate180<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1830}
1831
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001832TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001833 if (!GetParam()->typeSupported()) {
1834 GTEST_SKIP();
1835 }
Alec Mouric0aae732021-01-12 13:32:18 -08001836 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001837 fillBufferCheckersRotate270<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1838}
1839
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001840TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001841 if (!GetParam()->typeSupported()) {
1842 GTEST_SKIP();
1843 }
Alec Mouric0aae732021-01-12 13:32:18 -08001844 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001845 fillBufferLayerTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1846}
1847
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001848TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001849 if (!GetParam()->typeSupported()) {
1850 GTEST_SKIP();
1851 }
Alec Mouric0aae732021-01-12 13:32:18 -08001852 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08001853 fillBufferColorTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1854}
1855
Sally Qi2019fd22021-11-22 10:19:04 -08001856TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndSourceDataspace_opaqueBufferSource) {
1857 const auto& renderEngineFactory = GetParam();
1858 // skip for non color management
Alec Mouri47bcb072023-08-15 02:02:49 +00001859 if (!renderEngineFactory->typeSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001860 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001861 }
1862
1863 initializeRenderEngine();
1864 fillBufferColorTransformAndSourceDataspace<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1865}
1866
1867TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndOutputDataspace_opaqueBufferSource) {
1868 const auto& renderEngineFactory = GetParam();
1869 // skip for non color management
Alec Mouri47bcb072023-08-15 02:02:49 +00001870 if (!renderEngineFactory->typeSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001871 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001872 }
1873
1874 initializeRenderEngine();
1875 fillBufferColorTransformAndOutputDataspace<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1876}
1877
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001878TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001879 if (!GetParam()->typeSupported()) {
1880 GTEST_SKIP();
1881 }
Alec Mouric0aae732021-01-12 13:32:18 -08001882 initializeRenderEngine();
Alec Mouri7c94edb2018-12-03 21:23:26 -08001883 fillBufferWithRoundedCorners<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1884}
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001885
Alec Mouric0aae732021-01-12 13:32:18 -08001886TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001887 if (!GetParam()->typeSupported()) {
1888 GTEST_SKIP();
1889 }
Alec Mouric0aae732021-01-12 13:32:18 -08001890 initializeRenderEngine();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001891 fillBufferColorTransformZeroLayerAlpha<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1892}
Alec Mouri7c94edb2018-12-03 21:23:26 -08001893
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001894TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001895 if (!GetParam()->typeSupported()) {
1896 GTEST_SKIP();
1897 }
Alec Mouric0aae732021-01-12 13:32:18 -08001898 initializeRenderEngine();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001899 fillBufferAndBlurBackground<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1900}
1901
Alec Mourie8489fd2021-04-29 16:08:56 -07001902TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001903 if (!GetParam()->typeSupported()) {
1904 GTEST_SKIP();
1905 }
Alec Mourie8489fd2021-04-29 16:08:56 -07001906 initializeRenderEngine();
1907 fillSmallLayerAndBlurBackground<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1908}
1909
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001910TEST_P(RenderEngineTest, drawLayers_overlayCorners_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001911 if (!GetParam()->typeSupported()) {
1912 GTEST_SKIP();
1913 }
Alec Mouric0aae732021-01-12 13:32:18 -08001914 initializeRenderEngine();
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001915 overlayCorners<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1916}
1917
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001918TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001919 if (!GetParam()->typeSupported()) {
1920 GTEST_SKIP();
1921 }
Alec Mouric0aae732021-01-12 13:32:18 -08001922 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001923 fillRedBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1924}
1925
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001926TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001927 if (!GetParam()->typeSupported()) {
1928 GTEST_SKIP();
1929 }
Alec Mouric0aae732021-01-12 13:32:18 -08001930 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001931 fillGreenBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1932}
1933
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001934TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001935 if (!GetParam()->typeSupported()) {
1936 GTEST_SKIP();
1937 }
Alec Mouric0aae732021-01-12 13:32:18 -08001938 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001939 fillBlueBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1940}
1941
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001942TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001943 if (!GetParam()->typeSupported()) {
1944 GTEST_SKIP();
1945 }
Alec Mouric0aae732021-01-12 13:32:18 -08001946 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001947 fillRedTransparentBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1948}
1949
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001950TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001951 if (!GetParam()->typeSupported()) {
1952 GTEST_SKIP();
1953 }
Alec Mouric0aae732021-01-12 13:32:18 -08001954 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001955 fillBufferPhysicalOffset<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1956}
1957
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001958TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001959 if (!GetParam()->typeSupported()) {
1960 GTEST_SKIP();
1961 }
Alec Mouric0aae732021-01-12 13:32:18 -08001962 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001963 fillBufferCheckersRotate0<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1964}
1965
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001966TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001967 if (!GetParam()->typeSupported()) {
1968 GTEST_SKIP();
1969 }
Alec Mouric0aae732021-01-12 13:32:18 -08001970 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001971 fillBufferCheckersRotate90<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1972}
1973
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001974TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001975 if (!GetParam()->typeSupported()) {
1976 GTEST_SKIP();
1977 }
Alec Mouric0aae732021-01-12 13:32:18 -08001978 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001979 fillBufferCheckersRotate180<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1980}
1981
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001982TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001983 if (!GetParam()->typeSupported()) {
1984 GTEST_SKIP();
1985 }
Alec Mouric0aae732021-01-12 13:32:18 -08001986 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001987 fillBufferCheckersRotate270<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1988}
1989
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001990TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001991 if (!GetParam()->typeSupported()) {
1992 GTEST_SKIP();
1993 }
Alec Mouric0aae732021-01-12 13:32:18 -08001994 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001995 fillBufferLayerTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1996}
1997
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001998TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001999 if (!GetParam()->typeSupported()) {
2000 GTEST_SKIP();
2001 }
Alec Mouric0aae732021-01-12 13:32:18 -08002002 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08002003 fillBufferColorTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2004}
2005
Sally Qi2019fd22021-11-22 10:19:04 -08002006TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndSourceDataspace_bufferSource) {
2007 const auto& renderEngineFactory = GetParam();
2008 // skip for non color management
Alec Mouri47bcb072023-08-15 02:02:49 +00002009 if (!renderEngineFactory->typeSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00002010 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08002011 }
2012
2013 initializeRenderEngine();
2014 fillBufferColorTransformAndSourceDataspace<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2015}
2016
2017TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndOutputDataspace_bufferSource) {
2018 const auto& renderEngineFactory = GetParam();
2019 // skip for non color management
Alec Mouri47bcb072023-08-15 02:02:49 +00002020 if (!renderEngineFactory->typeSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00002021 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08002022 }
2023
2024 initializeRenderEngine();
2025 fillBufferColorTransformAndOutputDataspace<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2026}
2027
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002028TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002029 if (!GetParam()->typeSupported()) {
2030 GTEST_SKIP();
2031 }
Alec Mouric0aae732021-01-12 13:32:18 -08002032 initializeRenderEngine();
Alec Mouri7c94edb2018-12-03 21:23:26 -08002033 fillBufferWithRoundedCorners<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2034}
2035
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08002036TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002037 if (!GetParam()->typeSupported()) {
2038 GTEST_SKIP();
2039 }
Alec Mouric0aae732021-01-12 13:32:18 -08002040 initializeRenderEngine();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08002041 fillBufferColorTransformZeroLayerAlpha<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2042}
2043
Nathaniel Nifong53494f32021-04-30 14:05:39 -04002044TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002045 if (!GetParam()->typeSupported()) {
2046 GTEST_SKIP();
2047 }
Alec Mouric0aae732021-01-12 13:32:18 -08002048 initializeRenderEngine();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08002049 fillBufferAndBlurBackground<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2050}
2051
Alec Mourie8489fd2021-04-29 16:08:56 -07002052TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002053 if (!GetParam()->typeSupported()) {
2054 GTEST_SKIP();
2055 }
Alec Mourie8489fd2021-04-29 16:08:56 -07002056 initializeRenderEngine();
2057 fillSmallLayerAndBlurBackground<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2058}
2059
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002060TEST_P(RenderEngineTest, drawLayers_overlayCorners_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002061 if (!GetParam()->typeSupported()) {
2062 GTEST_SKIP();
2063 }
Alec Mouric0aae732021-01-12 13:32:18 -08002064 initializeRenderEngine();
Alec Mourie7d1d4a2019-02-05 01:13:46 +00002065 overlayCorners<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2066}
2067
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002068TEST_P(RenderEngineTest, drawLayers_fillBufferTextureTransform) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002069 if (!GetParam()->typeSupported()) {
2070 GTEST_SKIP();
2071 }
Alec Mouric0aae732021-01-12 13:32:18 -08002072 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002073 fillBufferTextureTransform();
2074}
2075
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002076TEST_P(RenderEngineTest, drawLayers_fillBuffer_premultipliesAlpha) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002077 if (!GetParam()->typeSupported()) {
2078 GTEST_SKIP();
2079 }
Alec Mouric0aae732021-01-12 13:32:18 -08002080 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002081 fillBufferWithPremultiplyAlpha();
2082}
2083
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002084TEST_P(RenderEngineTest, drawLayers_fillBuffer_withoutPremultiplyingAlpha) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002085 if (!GetParam()->typeSupported()) {
2086 GTEST_SKIP();
2087 }
Alec Mouric0aae732021-01-12 13:32:18 -08002088 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002089 fillBufferWithoutPremultiplyAlpha();
2090}
2091
Alec Mouribd17b3b2020-12-17 11:08:30 -08002092TEST_P(RenderEngineTest, drawLayers_fillShadow_castsWithoutCasterLayer) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002093 if (!GetParam()->typeSupported()) {
2094 GTEST_SKIP();
2095 }
Alec Mouric0aae732021-01-12 13:32:18 -08002096 initializeRenderEngine();
Alec Mouribd17b3b2020-12-17 11:08:30 -08002097
Alec Mouri4049b532021-10-15 20:59:33 -07002098 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2099 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Alec Mouribd17b3b2020-12-17 11:08:30 -08002100 const float shadowLength = 5.0f;
2101 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2102 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
Vishnu Naird9e4f462023-10-06 04:05:45 +00002103 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2104 shadowLength, false /* casterIsTranslucent */);
Alec Mouribd17b3b2020-12-17 11:08:30 -08002105
2106 drawShadowWithoutCaster(casterBounds.toFloatRect(), settings, backgroundColor);
2107 expectShadowColorWithoutCaster(casterBounds.toFloatRect(), settings, backgroundColor);
2108}
2109
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002110TEST_P(RenderEngineTest, drawLayers_fillShadow_casterLayerMinSize) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002111 if (!GetParam()->typeSupported()) {
2112 GTEST_SKIP();
2113 }
Alec Mouric0aae732021-01-12 13:32:18 -08002114 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002115
Alec Mouri4049b532021-10-15 20:59:33 -07002116 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2117 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2118 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2119 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002120 const float shadowLength = 5.0f;
2121 Rect casterBounds(1, 1);
2122 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2123 renderengine::LayerSettings castingLayer;
2124 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2125 castingLayer.alpha = 1.0f;
Vishnu Naird9e4f462023-10-06 04:05:45 +00002126 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2127 shadowLength, false /* casterIsTranslucent */);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002128
2129 drawShadow<ColorSourceVariant>(castingLayer, settings, casterColor, backgroundColor);
2130 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2131}
2132
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002133TEST_P(RenderEngineTest, drawLayers_fillShadow_casterColorLayer) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002134 if (!GetParam()->typeSupported()) {
2135 GTEST_SKIP();
2136 }
Alec Mouric0aae732021-01-12 13:32:18 -08002137 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002138
Alec Mouri4049b532021-10-15 20:59:33 -07002139 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2140 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2141 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2142 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002143 const float shadowLength = 5.0f;
2144 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2145 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2146 renderengine::LayerSettings castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002147 castingLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002148 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2149 castingLayer.alpha = 1.0f;
Vishnu Naird9e4f462023-10-06 04:05:45 +00002150 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2151 shadowLength, false /* casterIsTranslucent */);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002152
2153 drawShadow<ColorSourceVariant>(castingLayer, settings, casterColor, backgroundColor);
2154 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2155}
2156
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002157TEST_P(RenderEngineTest, drawLayers_fillShadow_casterOpaqueBufferLayer) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002158 if (!GetParam()->typeSupported()) {
2159 GTEST_SKIP();
2160 }
Alec Mouric0aae732021-01-12 13:32:18 -08002161 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002162
Alec Mouri4049b532021-10-15 20:59:33 -07002163 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2164 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2165 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2166 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002167 const float shadowLength = 5.0f;
2168 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2169 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2170 renderengine::LayerSettings castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002171 castingLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002172 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2173 castingLayer.alpha = 1.0f;
Vishnu Naird9e4f462023-10-06 04:05:45 +00002174 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2175 shadowLength, false /* casterIsTranslucent */);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002176
2177 drawShadow<BufferSourceVariant<ForceOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2178 backgroundColor);
2179 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2180}
2181
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002182TEST_P(RenderEngineTest, drawLayers_fillShadow_casterWithRoundedCorner) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002183 if (!GetParam()->typeSupported()) {
2184 GTEST_SKIP();
2185 }
Alec Mouric0aae732021-01-12 13:32:18 -08002186 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002187
Alec Mouri4049b532021-10-15 20:59:33 -07002188 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2189 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2190 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2191 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002192 const float shadowLength = 5.0f;
2193 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2194 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2195 renderengine::LayerSettings castingLayer;
2196 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002197 castingLayer.geometry.roundedCornersRadius = {3.0f, 3.0f};
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002198 castingLayer.geometry.roundedCornersCrop = casterBounds.toFloatRect();
2199 castingLayer.alpha = 1.0f;
Vishnu Naird9e4f462023-10-06 04:05:45 +00002200 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2201 shadowLength, false /* casterIsTranslucent */);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002202
2203 drawShadow<BufferSourceVariant<ForceOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2204 backgroundColor);
2205 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2206}
2207
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002208TEST_P(RenderEngineTest, drawLayers_fillShadow_translucentCasterWithAlpha) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002209 if (!GetParam()->typeSupported()) {
2210 GTEST_SKIP();
2211 }
Alec Mouric0aae732021-01-12 13:32:18 -08002212 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002213
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002214 const ubyte4 casterColor(255, 0, 0, 255);
2215 const ubyte4 backgroundColor(255, 255, 255, 255);
2216 const float shadowLength = 5.0f;
2217 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2218 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2219 renderengine::LayerSettings castingLayer;
2220 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2221 castingLayer.alpha = 0.5f;
Vishnu Naird9e4f462023-10-06 04:05:45 +00002222 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2223 shadowLength, true /* casterIsTranslucent */);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002224
2225 drawShadow<BufferSourceVariant<RelaxOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2226 backgroundColor);
2227
2228 // verify only the background since the shadow will draw behind the caster
2229 const float shadowInset = settings.length * -1.0f;
2230 const Rect casterWithShadow =
2231 Rect(casterBounds).inset(shadowInset, shadowInset, shadowInset, shadowInset);
2232 const Region backgroundRegion = Region(fullscreenRect()).subtractSelf(casterWithShadow);
2233 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
2234 backgroundColor.a);
2235}
2236
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002237TEST_P(RenderEngineTest, cleanupPostRender_cleansUpOnce) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002238 if (!GetParam()->typeSupported()) {
2239 GTEST_SKIP();
2240 }
Alec Mouric0aae732021-01-12 13:32:18 -08002241 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002242
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002243 renderengine::DisplaySettings settings;
2244 settings.physicalDisplay = fullscreenRect();
2245 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002246 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002247
Sally Qi59a9f502021-10-12 18:53:23 +00002248 std::vector<renderengine::LayerSettings> layers;
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002249 renderengine::LayerSettings layer;
2250 layer.geometry.boundaries = fullscreenRect().toFloatRect();
2251 BufferSourceVariant<ForceOpaqueBufferVariant>::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
2252 layer.alpha = 1.0;
Sally Qi59a9f502021-10-12 18:53:23 +00002253 layers.push_back(layer);
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002254
Patrick Williams2e9748f2022-08-09 22:48:18 +00002255 ftl::Future<FenceResult> futureOne =
Alec Mourif29700f2023-08-17 21:53:31 +00002256 mRE->drawLayers(settings, layers, mBuffer, base::unique_fd());
Patrick Williams2e9748f2022-08-09 22:48:18 +00002257 ASSERT_TRUE(futureOne.valid());
2258 auto resultOne = futureOne.get();
2259 ASSERT_TRUE(resultOne.ok());
2260 auto fenceOne = resultOne.value();
Sally Qi4cabdd02021-08-05 16:45:57 -07002261
Patrick Williams2e9748f2022-08-09 22:48:18 +00002262 ftl::Future<FenceResult> futureTwo =
Alec Mourif29700f2023-08-17 21:53:31 +00002263 mRE->drawLayers(settings, layers, mBuffer, base::unique_fd(fenceOne->dup()));
Patrick Williams2e9748f2022-08-09 22:48:18 +00002264 ASSERT_TRUE(futureTwo.valid());
2265 auto resultTwo = futureTwo.get();
2266 ASSERT_TRUE(resultTwo.ok());
2267 auto fenceTwo = resultTwo.value();
2268 fenceTwo->waitForever(LOG_TAG);
Derek Sollenbergerec411212021-08-25 10:54:47 -04002269
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002270 // Only cleanup the first time.
Ian Elliott1f0911e2022-09-09 16:31:47 -06002271 if (mRE->canSkipPostRenderCleanup()) {
2272 // Skia's Vk backend may keep the texture alive beyond drawLayersInternal, so
2273 // it never gets added to the cleanup list. In those cases, we can skip.
2274 EXPECT_TRUE(GetParam()->type() == renderengine::RenderEngine::RenderEngineType::SKIA_VK);
2275 } else {
2276 mRE->cleanupPostRender();
2277 EXPECT_TRUE(mRE->canSkipPostRenderCleanup());
2278 }
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002279}
2280
Ana Krulecf9a15d92020-12-11 08:35:00 -08002281TEST_P(RenderEngineTest, testRoundedCornersCrop) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002282 if (!GetParam()->typeSupported()) {
2283 GTEST_SKIP();
2284 }
Alec Mouric0aae732021-01-12 13:32:18 -08002285 initializeRenderEngine();
Ana Krulecf9a15d92020-12-11 08:35:00 -08002286
2287 renderengine::DisplaySettings settings;
2288 settings.physicalDisplay = fullscreenRect();
2289 settings.clip = fullscreenRect();
2290 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2291
Sally Qi59a9f502021-10-12 18:53:23 +00002292 std::vector<renderengine::LayerSettings> layers;
Ana Krulecf9a15d92020-12-11 08:35:00 -08002293
2294 renderengine::LayerSettings redLayer;
2295 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2296 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002297 redLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
2298
Ana Krulecf9a15d92020-12-11 08:35:00 -08002299 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2300 // Red background.
2301 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2302 redLayer.alpha = 1.0f;
2303
Sally Qi59a9f502021-10-12 18:53:23 +00002304 layers.push_back(redLayer);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002305
2306 // Green layer with 1/3 size.
2307 renderengine::LayerSettings greenLayer;
2308 greenLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2309 greenLayer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002310 greenLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
Ana Krulecf9a15d92020-12-11 08:35:00 -08002311 // Bottom right corner is not going to be rounded.
2312 greenLayer.geometry.roundedCornersCrop =
2313 Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3, DEFAULT_DISPLAY_HEIGHT,
2314 DEFAULT_DISPLAY_HEIGHT)
2315 .toFloatRect();
2316 greenLayer.source.solidColor = half3(0.0f, 1.0f, 0.0f);
2317 greenLayer.alpha = 1.0f;
2318
Sally Qi59a9f502021-10-12 18:53:23 +00002319 layers.push_back(greenLayer);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002320
Alec Mouric0aae732021-01-12 13:32:18 -08002321 invokeDraw(settings, layers);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002322
2323 // Corners should be ignored...
2324 // Screen size: width is 128, height is 256.
2325 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 0);
2326 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, 0, DEFAULT_DISPLAY_WIDTH, 1), 0, 0, 0, 0);
2327 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT - 1, 1, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
2328 // Bottom right corner is kept out of the clipping, and it's green.
2329 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1,
2330 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
2331 0, 255, 0, 255);
2332}
2333
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002334TEST_P(RenderEngineTest, testRoundedCornersParentCrop) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002335 if (!GetParam()->typeSupported()) {
2336 GTEST_SKIP();
2337 }
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002338 initializeRenderEngine();
2339
2340 renderengine::DisplaySettings settings;
2341 settings.physicalDisplay = fullscreenRect();
2342 settings.clip = fullscreenRect();
2343 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2344
Sally Qi59a9f502021-10-12 18:53:23 +00002345 std::vector<renderengine::LayerSettings> layers;
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002346
2347 renderengine::LayerSettings redLayer;
2348 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2349 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002350 redLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002351 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2352 // Red background.
2353 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2354 redLayer.alpha = 1.0f;
2355
Sally Qi59a9f502021-10-12 18:53:23 +00002356 layers.push_back(redLayer);
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002357
2358 // Green layer with 1/2 size with parent crop rect.
2359 renderengine::LayerSettings greenLayer = redLayer;
2360 greenLayer.geometry.boundaries =
2361 FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT / 2);
2362 greenLayer.source.solidColor = half3(0.0f, 1.0f, 0.0f);
2363
Sally Qi59a9f502021-10-12 18:53:23 +00002364 layers.push_back(greenLayer);
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002365
2366 invokeDraw(settings, layers);
2367
2368 // Due to roundedCornersRadius, the corners are untouched.
2369 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2370 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2371 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2372 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2373
2374 // top middle should be green and the bottom middle red
2375 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, 0), 0, 255, 0, 255);
2376 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0, 255);
2377
2378 // the bottom edge of the green layer should not be rounded
2379 expectBufferColor(Point(0, (DEFAULT_DISPLAY_HEIGHT / 2) - 1), 0, 255, 0, 255);
2380}
2381
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002382TEST_P(RenderEngineTest, testRoundedCornersParentCropSmallBounds) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002383 if (!GetParam()->typeSupported()) {
2384 GTEST_SKIP();
2385 }
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002386 initializeRenderEngine();
2387
2388 renderengine::DisplaySettings settings;
2389 settings.physicalDisplay = fullscreenRect();
2390 settings.clip = fullscreenRect();
2391 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2392
Sally Qi59a9f502021-10-12 18:53:23 +00002393 std::vector<renderengine::LayerSettings> layers;
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002394
2395 renderengine::LayerSettings redLayer;
2396 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2397 redLayer.geometry.boundaries = FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, 32);
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002398 redLayer.geometry.roundedCornersRadius = {64.0f, 64.0f};
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002399 redLayer.geometry.roundedCornersCrop = FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, 128);
2400 // Red background.
2401 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2402 redLayer.alpha = 1.0f;
2403
Sally Qi59a9f502021-10-12 18:53:23 +00002404 layers.push_back(redLayer);
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002405 invokeDraw(settings, layers);
2406
2407 // Due to roundedCornersRadius, the top corners are untouched.
2408 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2409 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2410
2411 // ensure that the entire height of the red layer was clipped by the rounded corners crop.
2412 expectBufferColor(Point(0, 31), 0, 0, 0, 0);
2413 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 31), 0, 0, 0, 0);
2414
2415 // the bottom middle should be red
2416 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, 31), 255, 0, 0, 255);
2417}
2418
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002419TEST_P(RenderEngineTest, testRoundedCornersXY) {
2420 if (GetParam()->type() != renderengine::RenderEngine::RenderEngineType::SKIA_GL) {
2421 GTEST_SKIP();
2422 }
2423
2424 initializeRenderEngine();
2425
2426 renderengine::DisplaySettings settings;
2427 settings.physicalDisplay = fullscreenRect();
2428 settings.clip = fullscreenRect();
2429 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2430
2431 std::vector<renderengine::LayerSettings> layers;
2432
2433 renderengine::LayerSettings redLayer;
2434 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2435 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
2436 redLayer.geometry.roundedCornersRadius = {5.0f, 20.0f};
2437 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2438 // Red background.
2439 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2440 redLayer.alpha = 1.0f;
2441
2442 layers.push_back(redLayer);
2443
2444 invokeDraw(settings, layers);
2445
2446 // Due to roundedCornersRadius, the corners are untouched.
2447 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2448 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2449 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2450 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2451
2452 // Y-axis draws a larger radius, check that its untouched as well
2453 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 5), 0, 0, 0, 0);
2454 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 5), 0, 0, 0, 0);
2455 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 5), 0, 0, 0, 0);
2456 expectBufferColor(Point(0, 5), 0, 0, 0, 0);
2457
2458 // middle should be red
2459 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0, 255);
2460}
2461
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002462TEST_P(RenderEngineTest, testClear) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002463 if (!GetParam()->typeSupported()) {
2464 GTEST_SKIP();
2465 }
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002466 initializeRenderEngine();
2467
2468 const auto rect = fullscreenRect();
2469 const renderengine::DisplaySettings display{
2470 .physicalDisplay = rect,
2471 .clip = rect,
2472 };
2473
2474 const renderengine::LayerSettings redLayer{
2475 .geometry.boundaries = rect.toFloatRect(),
2476 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
2477 .alpha = 1.0f,
2478 };
2479
2480 // This mimics prepareClearClientComposition. This layer should overwrite
2481 // the redLayer, so that the buffer is transparent, rather than red.
2482 const renderengine::LayerSettings clearLayer{
2483 .geometry.boundaries = rect.toFloatRect(),
2484 .source.solidColor = half3(0.0f, 0.0f, 0.0f),
2485 .alpha = 0.0f,
2486 .disableBlending = true,
2487 };
2488
Sally Qi59a9f502021-10-12 18:53:23 +00002489 std::vector<renderengine::LayerSettings> layers{redLayer, clearLayer};
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002490 invokeDraw(display, layers);
2491 expectBufferColor(rect, 0, 0, 0, 0);
2492}
2493
2494TEST_P(RenderEngineTest, testDisableBlendingBuffer) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002495 if (!GetParam()->typeSupported()) {
2496 GTEST_SKIP();
2497 }
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002498 initializeRenderEngine();
2499
2500 const auto rect = Rect(0, 0, 1, 1);
2501 const renderengine::DisplaySettings display{
2502 .physicalDisplay = rect,
2503 .clip = rect,
2504 };
2505
2506 const renderengine::LayerSettings redLayer{
2507 .geometry.boundaries = rect.toFloatRect(),
2508 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
2509 .alpha = 1.0f,
2510 };
2511
2512 // The next layer will overwrite redLayer with a GraphicBuffer that is green
2513 // applied with a translucent alpha.
Alec Mouria90a5702021-04-16 16:36:21 +00002514 const auto buf = allocateSourceBuffer(1, 1);
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002515 {
2516 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00002517 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2518 reinterpret_cast<void**>(&pixels));
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002519 pixels[0] = 0;
2520 pixels[1] = 255;
2521 pixels[2] = 0;
2522 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00002523 buf->getBuffer()->unlock();
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002524 }
2525
2526 const renderengine::LayerSettings greenLayer{
2527 .geometry.boundaries = rect.toFloatRect(),
2528 .source =
2529 renderengine::PixelSource{
2530 .buffer =
2531 renderengine::Buffer{
2532 .buffer = buf,
2533 .usePremultipliedAlpha = true,
2534 },
2535 },
2536 .alpha = 0.5f,
2537 .disableBlending = true,
2538 };
2539
Sally Qi59a9f502021-10-12 18:53:23 +00002540 std::vector<renderengine::LayerSettings> layers{redLayer, greenLayer};
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002541 invokeDraw(display, layers);
2542 expectBufferColor(rect, 0, 128, 0, 128);
2543}
2544
Tianhao Yao67dd7122022-02-22 17:48:33 +00002545TEST_P(RenderEngineTest, testBorder) {
2546 if (GetParam()->type() != renderengine::RenderEngine::RenderEngineType::SKIA_GL) {
2547 GTEST_SKIP();
2548 }
2549
Tianhao Yao67dd7122022-02-22 17:48:33 +00002550 initializeRenderEngine();
2551
2552 const ui::Dataspace dataspace = ui::Dataspace::V0_SRGB;
2553
2554 const auto displayRect = Rect(1080, 2280);
2555 renderengine::DisplaySettings display{
2556 .physicalDisplay = displayRect,
2557 .clip = displayRect,
2558 .outputDataspace = dataspace,
2559 };
2560 display.borderInfoList.clear();
2561 renderengine::BorderRenderInfo info;
2562 info.combinedRegion = Region(Rect(99, 99, 199, 199));
Tianhao Yao10cea3c2022-03-30 01:37:22 +00002563 info.width = 20.0f;
2564 info.color = half4{1.0f, 128.0f / 255.0f, 0.0f, 1.0f};
Tianhao Yao67dd7122022-02-22 17:48:33 +00002565 display.borderInfoList.emplace_back(info);
2566
2567 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2568 const renderengine::LayerSettings greenLayer{
2569 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2570 .source =
2571 renderengine::PixelSource{
2572 .buffer =
2573 renderengine::Buffer{
2574 .buffer = greenBuffer,
2575 .usePremultipliedAlpha = true,
2576 },
2577 },
2578 .alpha = 1.0f,
2579 .sourceDataspace = dataspace,
2580 .whitePointNits = 200.f,
2581 };
2582
2583 std::vector<renderengine::LayerSettings> layers;
2584 layers.emplace_back(greenLayer);
2585 invokeDraw(display, layers);
2586
2587 expectBufferColor(Rect(99, 99, 101, 101), 255, 128, 0, 255, 1);
2588}
2589
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002590TEST_P(RenderEngineTest, testDimming) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002591 if (!GetParam()->typeSupported()) {
2592 GTEST_SKIP();
2593 }
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002594 initializeRenderEngine();
2595
Alec Mouri85065692022-03-18 00:58:26 +00002596 const ui::Dataspace dataspace = ui::Dataspace::V0_SRGB_LINEAR;
2597
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002598 const auto displayRect = Rect(3, 1);
2599 const renderengine::DisplaySettings display{
2600 .physicalDisplay = displayRect,
2601 .clip = displayRect,
Alec Mouri85065692022-03-18 00:58:26 +00002602 .outputDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002603 .targetLuminanceNits = 1000.f,
2604 };
2605
2606 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2607 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2608 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2609
2610 const renderengine::LayerSettings greenLayer{
2611 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2612 .source =
2613 renderengine::PixelSource{
2614 .buffer =
2615 renderengine::Buffer{
2616 .buffer = greenBuffer,
2617 .usePremultipliedAlpha = true,
2618 },
2619 },
2620 .alpha = 1.0f,
Alec Mouri85065692022-03-18 00:58:26 +00002621 .sourceDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002622 .whitePointNits = 200.f,
2623 };
2624
2625 const renderengine::LayerSettings blueLayer{
2626 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2627 .source =
2628 renderengine::PixelSource{
2629 .buffer =
2630 renderengine::Buffer{
2631 .buffer = blueBuffer,
2632 .usePremultipliedAlpha = true,
2633 },
2634 },
2635 .alpha = 1.0f,
Alec Mouri85065692022-03-18 00:58:26 +00002636 .sourceDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002637 .whitePointNits = 1000.f / 51.f,
2638 };
2639
2640 const renderengine::LayerSettings redLayer{
2641 .geometry.boundaries = FloatRect(2.f, 0.f, 3.f, 1.f),
2642 .source =
2643 renderengine::PixelSource{
2644 .buffer =
2645 renderengine::Buffer{
2646 .buffer = redBuffer,
2647 .usePremultipliedAlpha = true,
2648 },
2649 },
2650 .alpha = 1.0f,
Alec Mouri85065692022-03-18 00:58:26 +00002651 .sourceDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002652 // When the white point is not set for a layer, just ignore it and treat it as the same
2653 // as the max layer
2654 .whitePointNits = -1.f,
2655 };
2656
2657 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer, redLayer};
2658 invokeDraw(display, layers);
2659
2660 expectBufferColor(Rect(1, 1), 0, 51, 0, 255, 1);
2661 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 5, 255, 1);
2662 expectBufferColor(Rect(2, 0, 3, 1), 51, 0, 0, 255, 1);
2663}
2664
Alec Mouri85065692022-03-18 00:58:26 +00002665TEST_P(RenderEngineTest, testDimming_inGammaSpace) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002666 if (!GetParam()->typeSupported()) {
2667 GTEST_SKIP();
2668 }
Alec Mouri85065692022-03-18 00:58:26 +00002669 initializeRenderEngine();
2670
2671 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2672 ui::Dataspace::TRANSFER_GAMMA2_2 |
2673 ui::Dataspace::RANGE_FULL);
2674
2675 const auto displayRect = Rect(3, 1);
2676 const renderengine::DisplaySettings display{
2677 .physicalDisplay = displayRect,
2678 .clip = displayRect,
2679 .outputDataspace = dataspace,
2680 .targetLuminanceNits = 1000.f,
2681 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2682 };
2683
2684 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2685 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2686 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2687
2688 const renderengine::LayerSettings greenLayer{
2689 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2690 .source =
2691 renderengine::PixelSource{
2692 .buffer =
2693 renderengine::Buffer{
2694 .buffer = greenBuffer,
2695 .usePremultipliedAlpha = true,
2696 },
2697 },
2698 .alpha = 1.0f,
2699 .sourceDataspace = dataspace,
2700 .whitePointNits = 200.f,
2701 };
2702
2703 const renderengine::LayerSettings blueLayer{
2704 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2705 .source =
2706 renderengine::PixelSource{
2707 .buffer =
2708 renderengine::Buffer{
2709 .buffer = blueBuffer,
2710 .usePremultipliedAlpha = true,
2711 },
2712 },
2713 .alpha = 1.0f,
2714 .sourceDataspace = dataspace,
2715 .whitePointNits = 1000.f / 51.f,
2716 };
2717
2718 const renderengine::LayerSettings redLayer{
2719 .geometry.boundaries = FloatRect(2.f, 0.f, 3.f, 1.f),
2720 .source =
2721 renderengine::PixelSource{
2722 .buffer =
2723 renderengine::Buffer{
2724 .buffer = redBuffer,
2725 .usePremultipliedAlpha = true,
2726 },
2727 },
2728 .alpha = 1.0f,
2729 .sourceDataspace = dataspace,
2730 // When the white point is not set for a layer, just ignore it and treat it as the same
2731 // as the max layer
2732 .whitePointNits = -1.f,
2733 };
2734
2735 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer, redLayer};
2736 invokeDraw(display, layers);
2737
2738 expectBufferColor(Rect(1, 1), 0, 122, 0, 255, 1);
2739 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 42, 255, 1);
2740 expectBufferColor(Rect(2, 0, 3, 1), 122, 0, 0, 255, 1);
2741}
2742
Alec Mouri9bcd1d12022-04-21 22:16:56 +00002743TEST_P(RenderEngineTest, testDimming_inGammaSpace_withDisplayColorTransform) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002744 if (!GetParam()->typeSupported()) {
2745 GTEST_SKIP();
2746 }
Alec Mouri9bcd1d12022-04-21 22:16:56 +00002747 initializeRenderEngine();
2748
2749 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2750 ui::Dataspace::TRANSFER_GAMMA2_2 |
2751 ui::Dataspace::RANGE_FULL);
2752
2753 const auto displayRect = Rect(3, 1);
2754 const renderengine::DisplaySettings display{
2755 .physicalDisplay = displayRect,
2756 .clip = displayRect,
2757 .outputDataspace = dataspace,
2758 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
2759 .targetLuminanceNits = 1000.f,
2760 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2761 };
2762
2763 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2764 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2765 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2766
2767 const renderengine::LayerSettings greenLayer{
2768 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2769 .source =
2770 renderengine::PixelSource{
2771 .buffer =
2772 renderengine::Buffer{
2773 .buffer = greenBuffer,
2774 .usePremultipliedAlpha = true,
2775 },
2776 },
2777 .alpha = 1.0f,
2778 .sourceDataspace = dataspace,
2779 .whitePointNits = 200.f,
2780 };
2781
2782 const renderengine::LayerSettings redLayer{
2783 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2784 .source =
2785 renderengine::PixelSource{
2786 .buffer =
2787 renderengine::Buffer{
2788 .buffer = redBuffer,
2789 .usePremultipliedAlpha = true,
2790 },
2791 },
2792 .alpha = 1.0f,
2793 .sourceDataspace = dataspace,
2794 // When the white point is not set for a layer, just ignore it and treat it as the same
2795 // as the max layer
2796 .whitePointNits = -1.f,
2797 };
2798
2799 std::vector<renderengine::LayerSettings> layers{greenLayer, redLayer};
2800 invokeDraw(display, layers);
2801
2802 expectBufferColor(Rect(1, 1), 0, 0, 0, 255, 1);
2803 expectBufferColor(Rect(1, 0, 2, 1), 0, 122, 0, 255, 1);
2804}
2805
2806TEST_P(RenderEngineTest, testDimming_inGammaSpace_withDisplayColorTransform_deviceHandles) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002807 if (!GetParam()->typeSupported()) {
2808 GTEST_SKIP();
2809 }
Alec Mouri9bcd1d12022-04-21 22:16:56 +00002810 initializeRenderEngine();
2811
2812 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2813 ui::Dataspace::TRANSFER_GAMMA2_2 |
2814 ui::Dataspace::RANGE_FULL);
2815
2816 const auto displayRect = Rect(3, 1);
2817 const renderengine::DisplaySettings display{
2818 .physicalDisplay = displayRect,
2819 .clip = displayRect,
2820 .outputDataspace = dataspace,
2821 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
2822 .deviceHandlesColorTransform = true,
2823 .targetLuminanceNits = 1000.f,
2824 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2825 };
2826
2827 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2828 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2829 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2830
2831 const renderengine::LayerSettings greenLayer{
2832 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2833 .source =
2834 renderengine::PixelSource{
2835 .buffer =
2836 renderengine::Buffer{
2837 .buffer = greenBuffer,
2838 .usePremultipliedAlpha = true,
2839 },
2840 },
2841 .alpha = 1.0f,
2842 .sourceDataspace = dataspace,
2843 .whitePointNits = 200.f,
2844 };
2845
2846 const renderengine::LayerSettings redLayer{
2847 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2848 .source =
2849 renderengine::PixelSource{
2850 .buffer =
2851 renderengine::Buffer{
2852 .buffer = redBuffer,
2853 .usePremultipliedAlpha = true,
2854 },
2855 },
2856 .alpha = 1.0f,
2857 .sourceDataspace = dataspace,
2858 // When the white point is not set for a layer, just ignore it and treat it as the same
2859 // as the max layer
2860 .whitePointNits = -1.f,
2861 };
2862
2863 std::vector<renderengine::LayerSettings> layers{greenLayer, redLayer};
2864 invokeDraw(display, layers);
2865
2866 expectBufferColor(Rect(1, 1), 0, 122, 0, 255, 1);
2867 expectBufferColor(Rect(1, 0, 2, 1), 122, 0, 0, 255, 1);
2868}
2869
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002870TEST_P(RenderEngineTest, testDimming_withoutTargetLuminance) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002871 if (!GetParam()->typeSupported()) {
2872 GTEST_SKIP();
2873 }
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002874 initializeRenderEngine();
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002875
2876 const auto displayRect = Rect(2, 1);
2877 const renderengine::DisplaySettings display{
2878 .physicalDisplay = displayRect,
2879 .clip = displayRect,
2880 .outputDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2881 .targetLuminanceNits = -1.f,
2882 };
2883
2884 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2885 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2886
2887 const renderengine::LayerSettings greenLayer{
2888 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2889 .source =
2890 renderengine::PixelSource{
2891 .buffer =
2892 renderengine::Buffer{
2893 .buffer = greenBuffer,
2894 .usePremultipliedAlpha = true,
2895 },
2896 },
2897 .alpha = 1.0f,
2898 .sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2899 .whitePointNits = 200.f,
2900 };
2901
2902 const renderengine::LayerSettings blueLayer{
2903 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2904 .source =
2905 renderengine::PixelSource{
2906 .buffer =
2907 renderengine::Buffer{
2908 .buffer = blueBuffer,
2909 .usePremultipliedAlpha = true,
2910 },
2911 },
2912 .alpha = 1.0f,
2913 .sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2914 .whitePointNits = 1000.f,
2915 };
2916
2917 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer};
2918 invokeDraw(display, layers);
2919
2920 expectBufferColor(Rect(1, 1), 0, 51, 0, 255, 1);
2921 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 255, 255);
2922}
2923
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002924TEST_P(RenderEngineTest, test_isOpaque) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002925 if (!GetParam()->typeSupported()) {
2926 GTEST_SKIP();
2927 }
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002928 initializeRenderEngine();
2929
2930 const auto rect = Rect(0, 0, 1, 1);
2931 const renderengine::DisplaySettings display{
2932 .physicalDisplay = rect,
2933 .clip = rect,
2934 .outputDataspace = ui::Dataspace::DISPLAY_P3,
2935 };
2936
2937 // Create an unpremul buffer that is green with no alpha. Using isOpaque
2938 // should make the green show.
2939 const auto buf = allocateSourceBuffer(1, 1);
2940 {
2941 uint8_t* pixels;
2942 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2943 reinterpret_cast<void**>(&pixels));
2944 pixels[0] = 0;
2945 pixels[1] = 255;
2946 pixels[2] = 0;
2947 pixels[3] = 0;
2948 buf->getBuffer()->unlock();
2949 }
2950
2951 const renderengine::LayerSettings greenLayer{
2952 .geometry.boundaries = rect.toFloatRect(),
2953 .source =
2954 renderengine::PixelSource{
2955 .buffer =
2956 renderengine::Buffer{
2957 .buffer = buf,
2958 // Although the pixels are not
2959 // premultiplied in practice, this
2960 // matches the input we see.
2961 .usePremultipliedAlpha = true,
2962 .isOpaque = true,
2963 },
2964 },
2965 .alpha = 1.0f,
2966 };
2967
Sally Qi59a9f502021-10-12 18:53:23 +00002968 std::vector<renderengine::LayerSettings> layers{greenLayer};
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002969 invokeDraw(display, layers);
2970
Alec Mouri47bcb072023-08-15 02:02:49 +00002971 expectBufferColor(rect, 117, 251, 76, 255);
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002972}
Alec Mouri4049b532021-10-15 20:59:33 -07002973
Alec Mouri4049b532021-10-15 20:59:33 -07002974TEST_P(RenderEngineTest, test_tonemapPQMatches) {
Alec Mouri47bcb072023-08-15 02:02:49 +00002975 if (!GetParam()->typeSupported()) {
Alec Mouri5a493722022-01-26 16:43:02 -08002976 GTEST_SKIP();
Alec Mouri4049b532021-10-15 20:59:33 -07002977 }
2978
Alec Mouri4049b532021-10-15 20:59:33 -07002979 initializeRenderEngine();
2980
Alec Mouri5a493722022-01-26 16:43:02 -08002981 tonemap(
2982 static_cast<ui::Dataspace>(HAL_DATASPACE_STANDARD_BT2020 |
2983 HAL_DATASPACE_TRANSFER_ST2084 | HAL_DATASPACE_RANGE_FULL),
2984 [](vec3 color) { return EOTF_PQ(color); },
2985 [](vec3 color, float) {
2986 static constexpr float kMaxPQLuminance = 10000.f;
2987 return color * kMaxPQLuminance;
2988 });
2989}
Alec Mouri4049b532021-10-15 20:59:33 -07002990
Alec Mouri5a493722022-01-26 16:43:02 -08002991TEST_P(RenderEngineTest, test_tonemapHLGMatches) {
Alec Mouri47bcb072023-08-15 02:02:49 +00002992 if (!GetParam()->typeSupported()) {
Alec Mouri5a493722022-01-26 16:43:02 -08002993 GTEST_SKIP();
Alec Mouri4049b532021-10-15 20:59:33 -07002994 }
2995
Alec Mouri5a493722022-01-26 16:43:02 -08002996 initializeRenderEngine();
Alec Mouri4049b532021-10-15 20:59:33 -07002997
Alec Mouri5a493722022-01-26 16:43:02 -08002998 tonemap(
2999 static_cast<ui::Dataspace>(HAL_DATASPACE_STANDARD_BT2020 | HAL_DATASPACE_TRANSFER_HLG |
3000 HAL_DATASPACE_RANGE_FULL),
3001 [](vec3 color) { return EOTF_HLG(color); },
3002 [](vec3 color, float currentLuminaceNits) {
3003 static constexpr float kMaxHLGLuminance = 1000.f;
Alec Mouri7a577452022-03-04 23:41:38 +00003004 return color * kMaxHLGLuminance;
Alec Mouri5a493722022-01-26 16:43:02 -08003005 });
Alec Mouri4049b532021-10-15 20:59:33 -07003006}
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -05003007
3008TEST_P(RenderEngineTest, r8_behaves_as_mask) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003009 if (!GetParam()->typeSupported()) {
3010 GTEST_SKIP();
3011 }
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -05003012 initializeRenderEngine();
3013
3014 const auto r8Buffer = allocateR8Buffer(2, 1);
3015 if (!r8Buffer) {
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003016 GTEST_SKIP() << "Test is only necessary on devices that support r8";
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -05003017 return;
3018 }
3019 {
3020 uint8_t* pixels;
3021 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
3022 reinterpret_cast<void**>(&pixels));
3023 // This will be drawn on top of a green buffer. We'll verify that 255
3024 // results in keeping the original green and 0 results in black.
3025 pixels[0] = 0;
3026 pixels[1] = 255;
3027 r8Buffer->getBuffer()->unlock();
3028 }
3029
3030 const auto rect = Rect(0, 0, 2, 1);
3031 const renderengine::DisplaySettings display{
3032 .physicalDisplay = rect,
3033 .clip = rect,
3034 .outputDataspace = ui::Dataspace::SRGB,
3035 };
3036
3037 const auto greenBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(0, 255, 0, 255));
3038 const renderengine::LayerSettings greenLayer{
3039 .geometry.boundaries = rect.toFloatRect(),
3040 .source =
3041 renderengine::PixelSource{
3042 .buffer =
3043 renderengine::Buffer{
3044 .buffer = greenBuffer,
3045 },
3046 },
3047 .alpha = 1.0f,
3048 };
3049 const renderengine::LayerSettings r8Layer{
3050 .geometry.boundaries = rect.toFloatRect(),
3051 .source =
3052 renderengine::PixelSource{
3053 .buffer =
3054 renderengine::Buffer{
3055 .buffer = r8Buffer,
3056 },
3057 },
3058 .alpha = 1.0f,
3059 };
3060
3061 std::vector<renderengine::LayerSettings> layers{greenLayer, r8Layer};
3062 invokeDraw(display, layers);
3063
3064 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 255);
3065 expectBufferColor(Rect(1, 0, 2, 1), 0, 255, 0, 255);
3066}
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003067
3068TEST_P(RenderEngineTest, r8_respects_color_transform) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003069 if (!GetParam()->typeSupported()) {
3070 GTEST_SKIP();
3071 }
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003072 initializeRenderEngine();
3073
3074 const auto r8Buffer = allocateR8Buffer(2, 1);
3075 if (!r8Buffer) {
3076 GTEST_SKIP() << "Test is only necessary on devices that support r8";
3077 return;
3078 }
3079 {
3080 uint8_t* pixels;
3081 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
3082 reinterpret_cast<void**>(&pixels));
3083 pixels[0] = 0;
3084 pixels[1] = 255;
3085 r8Buffer->getBuffer()->unlock();
3086 }
3087
3088 const auto rect = Rect(0, 0, 2, 1);
3089 const renderengine::DisplaySettings display{
3090 .physicalDisplay = rect,
3091 .clip = rect,
3092 .outputDataspace = ui::Dataspace::SRGB,
3093 // Verify that the R8 layer respects the color transform when
3094 // deviceHandlesColorTransform is false. This transform converts
3095 // pure red to pure green. That will occur when the R8 buffer is
3096 // 255. When the R8 buffer is 0, it will still change to black, as
3097 // with r8_behaves_as_mask.
Alec Mouri9bcd1d12022-04-21 22:16:56 +00003098 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003099 .deviceHandlesColorTransform = false,
3100 };
3101
3102 const auto redBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(255, 0, 0, 255));
3103 const renderengine::LayerSettings redLayer{
3104 .geometry.boundaries = rect.toFloatRect(),
3105 .source =
3106 renderengine::PixelSource{
3107 .buffer =
3108 renderengine::Buffer{
3109 .buffer = redBuffer,
3110 },
3111 },
3112 .alpha = 1.0f,
3113 };
3114 const renderengine::LayerSettings r8Layer{
3115 .geometry.boundaries = rect.toFloatRect(),
3116 .source =
3117 renderengine::PixelSource{
3118 .buffer =
3119 renderengine::Buffer{
3120 .buffer = r8Buffer,
3121 },
3122 },
3123 .alpha = 1.0f,
3124 };
3125
3126 std::vector<renderengine::LayerSettings> layers{redLayer, r8Layer};
3127 invokeDraw(display, layers);
3128
3129 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 255);
3130 expectBufferColor(Rect(1, 0, 2, 1), 0, 255, 0, 255);
3131}
3132
3133TEST_P(RenderEngineTest, r8_respects_color_transform_when_device_handles) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003134 if (!GetParam()->typeSupported()) {
3135 GTEST_SKIP();
3136 }
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003137 initializeRenderEngine();
3138
3139 const auto r8Buffer = allocateR8Buffer(2, 1);
3140 if (!r8Buffer) {
3141 GTEST_SKIP() << "Test is only necessary on devices that support r8";
3142 return;
3143 }
3144 {
3145 uint8_t* pixels;
3146 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
3147 reinterpret_cast<void**>(&pixels));
3148 pixels[0] = 0;
3149 pixels[1] = 255;
3150 r8Buffer->getBuffer()->unlock();
3151 }
3152
3153 const auto rect = Rect(0, 0, 2, 1);
3154 const renderengine::DisplaySettings display{
3155 .physicalDisplay = rect,
3156 .clip = rect,
3157 .outputDataspace = ui::Dataspace::SRGB,
3158 // If deviceHandlesColorTransform is true, pixels where the A8
3159 // buffer is opaque are unaffected. If the colorTransform is
3160 // invertible, pixels where the A8 buffer are transparent have the
3161 // inverse applied to them so that the DPU will convert them back to
3162 // black. Test with an arbitrary, invertible matrix.
3163 .colorTransform = mat4(1, 0, 0, 2,
3164 3, 1, 2, 5,
3165 0, 5, 3, 0,
3166 0, 1, 0, 2),
3167 .deviceHandlesColorTransform = true,
3168 };
3169
3170 const auto redBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(255, 0, 0, 255));
3171 const renderengine::LayerSettings redLayer{
3172 .geometry.boundaries = rect.toFloatRect(),
3173 .source =
3174 renderengine::PixelSource{
3175 .buffer =
3176 renderengine::Buffer{
3177 .buffer = redBuffer,
3178 },
3179 },
3180 .alpha = 1.0f,
3181 };
3182 const renderengine::LayerSettings r8Layer{
3183 .geometry.boundaries = rect.toFloatRect(),
3184 .source =
3185 renderengine::PixelSource{
3186 .buffer =
3187 renderengine::Buffer{
3188 .buffer = r8Buffer,
3189 },
3190 },
3191 .alpha = 1.0f,
3192 };
3193
3194 std::vector<renderengine::LayerSettings> layers{redLayer, r8Layer};
3195 invokeDraw(display, layers);
3196
3197 expectBufferColor(Rect(1, 0, 2, 1), 255, 0, 0, 255); // Still red.
3198 expectBufferColor(Rect(0, 0, 1, 1), 0, 70, 0, 255);
3199}
Leon Scroggins III45be9182022-04-27 10:37:11 -04003200
3201TEST_P(RenderEngineTest, primeShaderCache) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003202 if (!GetParam()->typeSupported()) {
3203 GTEST_SKIP();
3204 }
Leon Scroggins III45be9182022-04-27 10:37:11 -04003205 initializeRenderEngine();
3206
Bruno BELANYIb9b5b702023-10-13 13:25:11 +00003207 auto fut = mRE->primeCache(false);
Leon Scroggins III45be9182022-04-27 10:37:11 -04003208 if (fut.valid()) {
3209 fut.wait();
3210 }
3211
Alec Mouri47bcb072023-08-15 02:02:49 +00003212 static constexpr int kMinimumExpectedShadersCompiled = 60;
Leon Scroggins III45be9182022-04-27 10:37:11 -04003213 ASSERT_GT(static_cast<skia::SkiaGLRenderEngine*>(mRE.get())->reportShadersCompiled(),
Alec Mouri47bcb072023-08-15 02:02:49 +00003214 kMinimumExpectedShadersCompiled);
Leon Scroggins III45be9182022-04-27 10:37:11 -04003215}
Derek Sollenbergerd3f60652021-06-11 15:34:36 -04003216} // namespace renderengine
Alec Mouri6e57f682018-09-29 20:45:08 -07003217} // namespace android
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08003218
3219// TODO(b/129481165): remove the #pragma below and fix conversion issues
Marin Shalamanovbed7fd32020-12-21 20:02:20 +01003220#pragma clang diagnostic pop // ignored "-Wconversion -Wextra"