blob: 5eec305096fc943bf2587c7f17cd939e8274c976 [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,
406 const renderengine::ShadowSettings& shadow, const ubyte4& casterColor,
407 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
Alec Mouribd17b3b2020-12-17 11:08:30 -0800446 void expectShadowColorWithoutCaster(const FloatRect& casterBounds,
447 const renderengine::ShadowSettings& shadow,
448 const ubyte4& backgroundColor) {
449 const float shadowInset = shadow.length * -1.0f;
450 const Rect casterRect(casterBounds);
451 const Rect shadowRect =
452 Rect(casterRect).inset(shadowInset, shadowInset, shadowInset, shadowInset);
453
454 const Region backgroundRegion =
455 Region(fullscreenRect()).subtractSelf(casterRect).subtractSelf(shadowRect);
456
457 expectAlpha(shadowRect, 255);
458 // (0, 0, 0) fill on the bounds of the layer should be ignored.
459 expectBufferColor(casterRect, 255, 255, 255, 255, 254);
460
461 // verify background
462 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
463 backgroundColor.a);
464 }
465
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800466 static renderengine::ShadowSettings getShadowSettings(const vec2& casterPos, float shadowLength,
467 bool casterIsTranslucent) {
468 renderengine::ShadowSettings shadow;
469 shadow.ambientColor = {0.0f, 0.0f, 0.0f, 0.039f};
470 shadow.spotColor = {0.0f, 0.0f, 0.0f, 0.19f};
471 shadow.lightPos = vec3(casterPos.x, casterPos.y, 0);
472 shadow.lightRadius = 0.0f;
473 shadow.length = shadowLength;
474 shadow.casterIsTranslucent = casterIsTranslucent;
475 return shadow;
476 }
477
Alec Mouri1089aed2018-10-25 21:33:57 -0700478 static Rect fullscreenRect() { return Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT); }
479
480 static Rect offsetRect() {
481 return Rect(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_WIDTH,
482 DEFAULT_DISPLAY_HEIGHT);
483 }
484
485 static Rect offsetRectAtZero() {
486 return Rect(DEFAULT_DISPLAY_WIDTH - DEFAULT_DISPLAY_OFFSET,
487 DEFAULT_DISPLAY_HEIGHT - DEFAULT_DISPLAY_OFFSET);
488 }
489
Sally Qi59a9f502021-10-12 18:53:23 +0000490 void invokeDraw(const renderengine::DisplaySettings& settings,
491 const std::vector<renderengine::LayerSettings>& layers) {
Patrick Williams2e9748f2022-08-09 22:48:18 +0000492 ftl::Future<FenceResult> future =
Sally Qi4cabdd02021-08-05 16:45:57 -0700493 mRE->drawLayers(settings, layers, mBuffer, true, base::unique_fd());
Patrick Williams2e9748f2022-08-09 22:48:18 +0000494 ASSERT_TRUE(future.valid());
Sally Qi59a9f502021-10-12 18:53:23 +0000495
Patrick Williams2e9748f2022-08-09 22:48:18 +0000496 auto result = future.get();
497 ASSERT_TRUE(result.ok());
Alec Mouri1089aed2018-10-25 21:33:57 -0700498
Patrick Williams2e9748f2022-08-09 22:48:18 +0000499 auto fence = result.value();
500 fence->waitForever(LOG_TAG);
Alec Mouri1089aed2018-10-25 21:33:57 -0700501 }
502
Alec Mourid43ccab2019-03-13 12:23:45 -0700503 void drawEmptyLayers() {
Alec Mouri6e57f682018-09-29 20:45:08 -0700504 renderengine::DisplaySettings settings;
Sally Qi59a9f502021-10-12 18:53:23 +0000505 std::vector<renderengine::LayerSettings> layers;
Alec Mouric0aae732021-01-12 13:32:18 -0800506 invokeDraw(settings, layers);
Alec Mouri6e57f682018-09-29 20:45:08 -0700507 }
508
Alec Mouri1089aed2018-10-25 21:33:57 -0700509 template <typename SourceVariant>
510 void fillBuffer(half r, half g, half b, half a);
511
512 template <typename SourceVariant>
513 void fillRedBuffer();
514
515 template <typename SourceVariant>
516 void fillGreenBuffer();
517
518 template <typename SourceVariant>
519 void fillBlueBuffer();
520
521 template <typename SourceVariant>
522 void fillRedTransparentBuffer();
523
524 template <typename SourceVariant>
525 void fillRedOffsetBuffer();
526
527 template <typename SourceVariant>
528 void fillBufferPhysicalOffset();
529
530 template <typename SourceVariant>
Alec Mouri5a6d8572020-03-23 23:56:15 -0700531 void fillBufferCheckers(uint32_t rotation);
Alec Mouri1089aed2018-10-25 21:33:57 -0700532
533 template <typename SourceVariant>
534 void fillBufferCheckersRotate0();
535
536 template <typename SourceVariant>
537 void fillBufferCheckersRotate90();
538
539 template <typename SourceVariant>
540 void fillBufferCheckersRotate180();
541
542 template <typename SourceVariant>
543 void fillBufferCheckersRotate270();
544
545 template <typename SourceVariant>
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800546 void fillBufferWithLayerTransform();
547
548 template <typename SourceVariant>
Alec Mouri1089aed2018-10-25 21:33:57 -0700549 void fillBufferLayerTransform();
550
551 template <typename SourceVariant>
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800552 void fillBufferWithColorTransform();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800553
554 template <typename SourceVariant>
Alec Mouri1089aed2018-10-25 21:33:57 -0700555 void fillBufferColorTransform();
556
Alec Mouri7c94edb2018-12-03 21:23:26 -0800557 template <typename SourceVariant>
Sally Qi2019fd22021-11-22 10:19:04 -0800558 void fillBufferWithColorTransformAndSourceDataspace(const ui::Dataspace sourceDataspace);
559
560 template <typename SourceVariant>
561 void fillBufferColorTransformAndSourceDataspace();
562
563 template <typename SourceVariant>
564 void fillBufferWithColorTransformAndOutputDataspace(const ui::Dataspace outputDataspace);
565
566 template <typename SourceVariant>
567 void fillBufferColorTransformAndOutputDataspace();
568
569 template <typename SourceVariant>
KaiChieh Chuangda2845c2020-12-14 16:49:38 +0800570 void fillBufferWithColorTransformZeroLayerAlpha();
571
572 template <typename SourceVariant>
573 void fillBufferColorTransformZeroLayerAlpha();
574
575 template <typename SourceVariant>
Alec Mouri7c94edb2018-12-03 21:23:26 -0800576 void fillRedBufferWithRoundedCorners();
577
578 template <typename SourceVariant>
579 void fillBufferWithRoundedCorners();
580
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000581 template <typename SourceVariant>
Lucas Dupin19c8f0e2019-11-25 17:55:44 -0800582 void fillBufferAndBlurBackground();
583
584 template <typename SourceVariant>
Alec Mourie8489fd2021-04-29 16:08:56 -0700585 void fillSmallLayerAndBlurBackground();
586
587 template <typename SourceVariant>
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000588 void overlayCorners();
589
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800590 void fillRedBufferTextureTransform();
591
592 void fillBufferTextureTransform();
593
594 void fillRedBufferWithPremultiplyAlpha();
595
596 void fillBufferWithPremultiplyAlpha();
597
598 void fillRedBufferWithoutPremultiplyAlpha();
599
600 void fillBufferWithoutPremultiplyAlpha();
601
Alec Mouriac335532018-11-12 15:01:33 -0800602 void fillGreenColorBufferThenClearRegion();
603
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800604 template <typename SourceVariant>
605 void drawShadow(const renderengine::LayerSettings& castingLayer,
606 const renderengine::ShadowSettings& shadow, const ubyte4& casterColor,
607 const ubyte4& backgroundColor);
608
Alec Mouribd17b3b2020-12-17 11:08:30 -0800609 void drawShadowWithoutCaster(const FloatRect& castingBounds,
610 const renderengine::ShadowSettings& shadow,
611 const ubyte4& backgroundColor);
612
Alec Mouri5a493722022-01-26 16:43:02 -0800613 // Tonemaps grey values from sourceDataspace -> Display P3 and checks that GPU and CPU
614 // implementations are identical Also implicitly checks that the injected tonemap shader
615 // compiles
616 void tonemap(ui::Dataspace sourceDataspace, std::function<vec3(vec3)> eotf,
617 std::function<vec3(vec3, float)> scaleOotf);
618
Alec Mouric0aae732021-01-12 13:32:18 -0800619 void initializeRenderEngine();
620
621 std::unique_ptr<renderengine::RenderEngine> mRE;
Alec Mouria90a5702021-04-16 16:36:21 +0000622 std::shared_ptr<renderengine::ExternalTexture> mBuffer;
Alec Mouri6e57f682018-09-29 20:45:08 -0700623};
624
Alec Mouric0aae732021-01-12 13:32:18 -0800625void RenderEngineTest::initializeRenderEngine() {
626 const auto& renderEngineFactory = GetParam();
Alec Mouric16974e2022-09-13 17:35:48 +0000627 mRE = renderEngineFactory->createRenderEngine();
Alec Mouria90a5702021-04-16 16:36:21 +0000628 mBuffer = allocateDefaultBuffer();
Alec Mouric0aae732021-01-12 13:32:18 -0800629}
630
Alec Mouri1089aed2018-10-25 21:33:57 -0700631struct ColorSourceVariant {
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800632 static void fillColor(renderengine::LayerSettings& layer, half r, half g, half b,
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800633 RenderEngineTest* /*fixture*/) {
Alec Mouri1089aed2018-10-25 21:33:57 -0700634 layer.source.solidColor = half3(r, g, b);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800635 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700636 }
637};
638
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800639struct RelaxOpaqueBufferVariant {
640 static void setOpaqueBit(renderengine::LayerSettings& layer) {
641 layer.source.buffer.isOpaque = false;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800642 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800643 }
644
645 static uint8_t getAlphaChannel() { return 255; }
646};
647
648struct ForceOpaqueBufferVariant {
649 static void setOpaqueBit(renderengine::LayerSettings& layer) {
650 layer.source.buffer.isOpaque = true;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800651 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800652 }
653
654 static uint8_t getAlphaChannel() {
655 // The isOpaque bit will override the alpha channel, so this should be
656 // arbitrary.
Alec Mouric0aae732021-01-12 13:32:18 -0800657 return 50;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800658 }
659};
660
661template <typename OpaquenessVariant>
662struct BufferSourceVariant {
663 static void fillColor(renderengine::LayerSettings& layer, half r, half g, half b,
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800664 RenderEngineTest* fixture) {
Alec Mouria90a5702021-04-16 16:36:21 +0000665 const auto buf = fixture->allocateSourceBuffer(1, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800666
667 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +0000668 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
669 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800670
Alec Mouria90a5702021-04-16 16:36:21 +0000671 for (int32_t j = 0; j < buf->getBuffer()->getHeight(); j++) {
672 uint8_t* iter = pixels + (buf->getBuffer()->getStride() * j) * 4;
673 for (int32_t i = 0; i < buf->getBuffer()->getWidth(); i++) {
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800674 iter[0] = uint8_t(r * 255);
675 iter[1] = uint8_t(g * 255);
676 iter[2] = uint8_t(b * 255);
677 iter[3] = OpaquenessVariant::getAlphaChannel();
678 iter += 4;
679 }
680 }
681
Alec Mouria90a5702021-04-16 16:36:21 +0000682 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800683
684 layer.source.buffer.buffer = buf;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800685 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800686 OpaquenessVariant::setOpaqueBit(layer);
687 }
688};
689
Alec Mouri1089aed2018-10-25 21:33:57 -0700690template <typename SourceVariant>
691void RenderEngineTest::fillBuffer(half r, half g, half b, half a) {
692 renderengine::DisplaySettings settings;
693 settings.physicalDisplay = fullscreenRect();
694 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800695 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700696
Sally Qi59a9f502021-10-12 18:53:23 +0000697 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700698
699 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800700 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700701 layer.geometry.boundaries = fullscreenRect().toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800702 SourceVariant::fillColor(layer, r, g, b, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700703 layer.alpha = a;
704
Sally Qi59a9f502021-10-12 18:53:23 +0000705 layers.push_back(layer);
Alec Mouri1089aed2018-10-25 21:33:57 -0700706
Alec Mouric0aae732021-01-12 13:32:18 -0800707 invokeDraw(settings, layers);
Alec Mouri1089aed2018-10-25 21:33:57 -0700708}
709
710template <typename SourceVariant>
711void RenderEngineTest::fillRedBuffer() {
712 fillBuffer<SourceVariant>(1.0f, 0.0f, 0.0f, 1.0f);
713 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
714}
715
716template <typename SourceVariant>
717void RenderEngineTest::fillGreenBuffer() {
718 fillBuffer<SourceVariant>(0.0f, 1.0f, 0.0f, 1.0f);
719 expectBufferColor(fullscreenRect(), 0, 255, 0, 255);
720}
721
722template <typename SourceVariant>
723void RenderEngineTest::fillBlueBuffer() {
724 fillBuffer<SourceVariant>(0.0f, 0.0f, 1.0f, 1.0f);
725 expectBufferColor(fullscreenRect(), 0, 0, 255, 255);
726}
727
728template <typename SourceVariant>
729void RenderEngineTest::fillRedTransparentBuffer() {
730 fillBuffer<SourceVariant>(1.0f, 0.0f, 0.0f, .2f);
731 expectBufferColor(fullscreenRect(), 51, 0, 0, 51);
732}
733
734template <typename SourceVariant>
735void RenderEngineTest::fillRedOffsetBuffer() {
736 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800737 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700738 settings.physicalDisplay = offsetRect();
739 settings.clip = offsetRectAtZero();
740
Sally Qi59a9f502021-10-12 18:53:23 +0000741 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700742
743 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800744 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700745 layer.geometry.boundaries = offsetRectAtZero().toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800746 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700747 layer.alpha = 1.0f;
748
Sally Qi59a9f502021-10-12 18:53:23 +0000749 layers.push_back(layer);
Alec Mouric0aae732021-01-12 13:32:18 -0800750 invokeDraw(settings, layers);
Alec Mouri1089aed2018-10-25 21:33:57 -0700751}
752
753template <typename SourceVariant>
754void RenderEngineTest::fillBufferPhysicalOffset() {
755 fillRedOffsetBuffer<SourceVariant>();
756
757 expectBufferColor(Rect(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_WIDTH,
758 DEFAULT_DISPLAY_HEIGHT),
759 255, 0, 0, 255);
760 Rect offsetRegionLeft(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_HEIGHT);
761 Rect offsetRegionTop(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_OFFSET);
762
763 expectBufferColor(offsetRegionLeft, 0, 0, 0, 0);
764 expectBufferColor(offsetRegionTop, 0, 0, 0, 0);
765}
766
767template <typename SourceVariant>
Alec Mouri5a6d8572020-03-23 23:56:15 -0700768void RenderEngineTest::fillBufferCheckers(uint32_t orientationFlag) {
Alec Mouri1089aed2018-10-25 21:33:57 -0700769 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800770 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700771 settings.physicalDisplay = fullscreenRect();
772 // Here logical space is 2x2
773 settings.clip = Rect(2, 2);
Alec Mouri5a6d8572020-03-23 23:56:15 -0700774 settings.orientation = orientationFlag;
Alec Mouri1089aed2018-10-25 21:33:57 -0700775
Sally Qi59a9f502021-10-12 18:53:23 +0000776 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700777
778 renderengine::LayerSettings layerOne;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800779 layerOne.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700780 Rect rectOne(0, 0, 1, 1);
781 layerOne.geometry.boundaries = rectOne.toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800782 SourceVariant::fillColor(layerOne, 1.0f, 0.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700783 layerOne.alpha = 1.0f;
784
785 renderengine::LayerSettings layerTwo;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800786 layerTwo.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700787 Rect rectTwo(0, 1, 1, 2);
788 layerTwo.geometry.boundaries = rectTwo.toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800789 SourceVariant::fillColor(layerTwo, 0.0f, 1.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700790 layerTwo.alpha = 1.0f;
791
792 renderengine::LayerSettings layerThree;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800793 layerThree.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700794 Rect rectThree(1, 0, 2, 1);
795 layerThree.geometry.boundaries = rectThree.toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800796 SourceVariant::fillColor(layerThree, 0.0f, 0.0f, 1.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700797 layerThree.alpha = 1.0f;
798
Sally Qi59a9f502021-10-12 18:53:23 +0000799 layers.push_back(layerOne);
800 layers.push_back(layerTwo);
801 layers.push_back(layerThree);
Alec Mouri1089aed2018-10-25 21:33:57 -0700802
Alec Mouric0aae732021-01-12 13:32:18 -0800803 invokeDraw(settings, layers);
Alec Mouri1089aed2018-10-25 21:33:57 -0700804}
805
806template <typename SourceVariant>
807void RenderEngineTest::fillBufferCheckersRotate0() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700808 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_0);
Alec Mouri1089aed2018-10-25 21:33:57 -0700809 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0,
810 255);
811 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
812 DEFAULT_DISPLAY_HEIGHT / 2),
813 0, 0, 255, 255);
814 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
815 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
816 0, 0, 0, 0);
817 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
818 DEFAULT_DISPLAY_HEIGHT),
819 0, 255, 0, 255);
820}
821
822template <typename SourceVariant>
823void RenderEngineTest::fillBufferCheckersRotate90() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700824 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_90);
Alec Mouri1089aed2018-10-25 21:33:57 -0700825 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 255, 0,
826 255);
827 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
828 DEFAULT_DISPLAY_HEIGHT / 2),
829 255, 0, 0, 255);
830 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
831 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
832 0, 0, 255, 255);
833 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
834 DEFAULT_DISPLAY_HEIGHT),
835 0, 0, 0, 0);
836}
837
838template <typename SourceVariant>
839void RenderEngineTest::fillBufferCheckersRotate180() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700840 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_180);
Alec Mouri1089aed2018-10-25 21:33:57 -0700841 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 0,
842 0);
843 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
844 DEFAULT_DISPLAY_HEIGHT / 2),
845 0, 255, 0, 255);
846 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
847 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
848 255, 0, 0, 255);
849 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
850 DEFAULT_DISPLAY_HEIGHT),
851 0, 0, 255, 255);
852}
853
854template <typename SourceVariant>
855void RenderEngineTest::fillBufferCheckersRotate270() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700856 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_270);
Alec Mouri1089aed2018-10-25 21:33:57 -0700857 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 255,
858 255);
859 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
860 DEFAULT_DISPLAY_HEIGHT / 2),
861 0, 0, 0, 0);
862 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
863 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
864 0, 255, 0, 255);
865 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
866 DEFAULT_DISPLAY_HEIGHT),
867 255, 0, 0, 255);
868}
869
870template <typename SourceVariant>
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800871void RenderEngineTest::fillBufferWithLayerTransform() {
Alec Mouri1089aed2018-10-25 21:33:57 -0700872 renderengine::DisplaySettings settings;
873 settings.physicalDisplay = fullscreenRect();
874 // Here logical space is 2x2
875 settings.clip = Rect(2, 2);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800876 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700877
Sally Qi59a9f502021-10-12 18:53:23 +0000878 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700879
880 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800881 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700882 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
883 // Translate one pixel diagonally
884 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 -0800885 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700886 layer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
887 layer.alpha = 1.0f;
888
Sally Qi59a9f502021-10-12 18:53:23 +0000889 layers.push_back(layer);
Alec Mouri1089aed2018-10-25 21:33:57 -0700890
Alec Mouric0aae732021-01-12 13:32:18 -0800891 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800892}
Alec Mouri1089aed2018-10-25 21:33:57 -0700893
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800894template <typename SourceVariant>
895void RenderEngineTest::fillBufferLayerTransform() {
896 fillBufferWithLayerTransform<SourceVariant>();
Alec Mouri1089aed2018-10-25 21:33:57 -0700897 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 0, 0);
898 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
899 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
900 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
901 255, 0, 0, 255);
902}
903
904template <typename SourceVariant>
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800905void RenderEngineTest::fillBufferWithColorTransform() {
Alec Mouri1089aed2018-10-25 21:33:57 -0700906 renderengine::DisplaySettings settings;
907 settings.physicalDisplay = fullscreenRect();
908 settings.clip = Rect(1, 1);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800909 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700910
Sally Qi59a9f502021-10-12 18:53:23 +0000911 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700912
913 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800914 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700915 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800916 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700917 layer.alpha = 1.0f;
918
919 // construct a fake color matrix
920 // annihilate green and blue channels
KaiChieh Chuang436fc192020-09-07 13:48:42 +0800921 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
Alec Mouri1089aed2018-10-25 21:33:57 -0700922 // set red channel to red + green
923 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
924
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800925 layer.alpha = 1.0f;
926 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
927
Sally Qi59a9f502021-10-12 18:53:23 +0000928 layers.push_back(layer);
Alec Mouri1089aed2018-10-25 21:33:57 -0700929
Alec Mouric0aae732021-01-12 13:32:18 -0800930 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800931}
Alec Mouri1089aed2018-10-25 21:33:57 -0700932
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800933template <typename SourceVariant>
Sally Qi2019fd22021-11-22 10:19:04 -0800934void RenderEngineTest::fillBufferWithColorTransformAndSourceDataspace(
935 const ui::Dataspace sourceDataspace) {
936 renderengine::DisplaySettings settings;
937 settings.physicalDisplay = fullscreenRect();
938 settings.clip = Rect(1, 1);
939 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
940
941 std::vector<renderengine::LayerSettings> layers;
942
943 renderengine::LayerSettings layer;
Sally Qi2019fd22021-11-22 10:19:04 -0800944 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
945 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
Alec Mouric16974e2022-09-13 17:35:48 +0000946 layer.sourceDataspace = sourceDataspace;
Sally Qi2019fd22021-11-22 10:19:04 -0800947 layer.alpha = 1.0f;
948
949 // construct a fake color matrix
950 // annihilate green and blue channels
951 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
952 // set red channel to red + green
953 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
954
955 layer.alpha = 1.0f;
956 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
957
958 layers.push_back(layer);
959
960 invokeDraw(settings, layers);
961}
962
963template <typename SourceVariant>
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800964void RenderEngineTest::fillBufferColorTransform() {
965 fillBufferWithColorTransform<SourceVariant>();
KaiChieh Chuang436fc192020-09-07 13:48:42 +0800966 expectBufferColor(fullscreenRect(), 172, 0, 0, 255, 1);
967}
968
969template <typename SourceVariant>
Sally Qi2019fd22021-11-22 10:19:04 -0800970void RenderEngineTest::fillBufferColorTransformAndSourceDataspace() {
971 unordered_map<ui::Dataspace, ubyte4> dataspaceToColorMap;
Alec Mouric16974e2022-09-13 17:35:48 +0000972 dataspaceToColorMap[ui::Dataspace::V0_BT709] = {77, 0, 0, 255};
973 dataspaceToColorMap[ui::Dataspace::BT2020] = {101, 0, 0, 255};
974 dataspaceToColorMap[ui::Dataspace::ADOBE_RGB] = {75, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -0800975 ui::Dataspace customizedDataspace = static_cast<ui::Dataspace>(
976 ui::Dataspace::STANDARD_BT709 | ui::Dataspace::TRANSFER_GAMMA2_2 |
977 ui::Dataspace::RANGE_FULL);
Alec Mouric16974e2022-09-13 17:35:48 +0000978 dataspaceToColorMap[customizedDataspace] = {61, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -0800979 for (const auto& [sourceDataspace, color] : dataspaceToColorMap) {
980 fillBufferWithColorTransformAndSourceDataspace<SourceVariant>(sourceDataspace);
981 expectBufferColor(fullscreenRect(), color.r, color.g, color.b, color.a, 1);
982 }
983}
984
985template <typename SourceVariant>
986void RenderEngineTest::fillBufferWithColorTransformAndOutputDataspace(
987 const ui::Dataspace outputDataspace) {
988 renderengine::DisplaySettings settings;
989 settings.physicalDisplay = fullscreenRect();
990 settings.clip = Rect(1, 1);
991 settings.outputDataspace = outputDataspace;
992
993 std::vector<renderengine::LayerSettings> layers;
994
995 renderengine::LayerSettings layer;
996 layer.sourceDataspace = ui::Dataspace::V0_SCRGB_LINEAR;
997 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
998 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
999 layer.alpha = 1.0f;
1000
1001 // construct a fake color matrix
1002 // annihilate green and blue channels
1003 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
1004 // set red channel to red + green
1005 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
1006
1007 layer.alpha = 1.0f;
1008 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1009
1010 layers.push_back(layer);
1011
1012 invokeDraw(settings, layers);
1013}
1014
1015template <typename SourceVariant>
1016void RenderEngineTest::fillBufferColorTransformAndOutputDataspace() {
1017 unordered_map<ui::Dataspace, ubyte4> dataspaceToColorMap;
Alec Mouric16974e2022-09-13 17:35:48 +00001018 dataspaceToColorMap[ui::Dataspace::V0_BT709] = {198, 0, 0, 255};
1019 dataspaceToColorMap[ui::Dataspace::BT2020] = {187, 0, 0, 255};
1020 dataspaceToColorMap[ui::Dataspace::ADOBE_RGB] = {192, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -08001021 ui::Dataspace customizedDataspace = static_cast<ui::Dataspace>(
1022 ui::Dataspace::STANDARD_BT709 | ui::Dataspace::TRANSFER_GAMMA2_6 |
1023 ui::Dataspace::RANGE_FULL);
Alec Mouric16974e2022-09-13 17:35:48 +00001024 dataspaceToColorMap[customizedDataspace] = {205, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -08001025 for (const auto& [outputDataspace, color] : dataspaceToColorMap) {
1026 fillBufferWithColorTransformAndOutputDataspace<SourceVariant>(outputDataspace);
1027 expectBufferColor(fullscreenRect(), color.r, color.g, color.b, color.a, 1);
1028 }
1029}
1030
1031template <typename SourceVariant>
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001032void RenderEngineTest::fillBufferWithColorTransformZeroLayerAlpha() {
1033 renderengine::DisplaySettings settings;
1034 settings.physicalDisplay = fullscreenRect();
1035 settings.clip = Rect(1, 1);
1036
Sally Qi59a9f502021-10-12 18:53:23 +00001037 std::vector<renderengine::LayerSettings> layers;
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001038
1039 renderengine::LayerSettings layer;
1040 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1041 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
1042 layer.alpha = 0;
1043
1044 // construct a fake color matrix
1045 // simple inverse color
1046 settings.colorTransform = mat4(-1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 1, 1, 1, 1);
1047
1048 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1049
Sally Qi59a9f502021-10-12 18:53:23 +00001050 layers.push_back(layer);
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001051
Alec Mouric0aae732021-01-12 13:32:18 -08001052 invokeDraw(settings, layers);
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001053}
1054
1055template <typename SourceVariant>
1056void RenderEngineTest::fillBufferColorTransformZeroLayerAlpha() {
1057 fillBufferWithColorTransformZeroLayerAlpha<SourceVariant>();
1058 expectBufferColor(fullscreenRect(), 0, 0, 0, 0);
1059}
1060
1061template <typename SourceVariant>
Alec Mouri7c94edb2018-12-03 21:23:26 -08001062void RenderEngineTest::fillRedBufferWithRoundedCorners() {
1063 renderengine::DisplaySettings settings;
1064 settings.physicalDisplay = fullscreenRect();
1065 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001066 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri7c94edb2018-12-03 21:23:26 -08001067
Sally Qi59a9f502021-10-12 18:53:23 +00001068 std::vector<renderengine::LayerSettings> layers;
Alec Mouri7c94edb2018-12-03 21:23:26 -08001069
1070 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001071 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri7c94edb2018-12-03 21:23:26 -08001072 layer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07001073 layer.geometry.roundedCornersRadius = {5.0f, 5.0f};
Alec Mouri7c94edb2018-12-03 21:23:26 -08001074 layer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
1075 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
1076 layer.alpha = 1.0f;
1077
Sally Qi59a9f502021-10-12 18:53:23 +00001078 layers.push_back(layer);
Alec Mouri7c94edb2018-12-03 21:23:26 -08001079
Alec Mouric0aae732021-01-12 13:32:18 -08001080 invokeDraw(settings, layers);
Alec Mouri7c94edb2018-12-03 21:23:26 -08001081}
1082
1083template <typename SourceVariant>
1084void RenderEngineTest::fillBufferWithRoundedCorners() {
1085 fillRedBufferWithRoundedCorners<SourceVariant>();
1086 // Corners should be ignored...
1087 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 0);
1088 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, 0, DEFAULT_DISPLAY_WIDTH, 1), 0, 0, 0, 0);
1089 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT - 1, 1, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
1090 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1,
1091 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1092 0, 0, 0, 0);
1093 // ...And the non-rounded portion should be red.
1094 // Other pixels may be anti-aliased, so let's not check those.
1095 expectBufferColor(Rect(5, 5, DEFAULT_DISPLAY_WIDTH - 5, DEFAULT_DISPLAY_HEIGHT - 5), 255, 0, 0,
1096 255);
1097}
1098
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001099template <typename SourceVariant>
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001100void RenderEngineTest::fillBufferAndBlurBackground() {
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001101 auto blurRadius = 50;
1102 auto center = DEFAULT_DISPLAY_WIDTH / 2;
1103
1104 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001105 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001106 settings.physicalDisplay = fullscreenRect();
1107 settings.clip = fullscreenRect();
1108
Sally Qi59a9f502021-10-12 18:53:23 +00001109 std::vector<renderengine::LayerSettings> layers;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001110
1111 renderengine::LayerSettings backgroundLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001112 backgroundLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001113 backgroundLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1114 SourceVariant::fillColor(backgroundLayer, 0.0f, 1.0f, 0.0f, this);
1115 backgroundLayer.alpha = 1.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001116 layers.emplace_back(backgroundLayer);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001117
1118 renderengine::LayerSettings leftLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001119 leftLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001120 leftLayer.geometry.boundaries =
1121 Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT).toFloatRect();
1122 SourceVariant::fillColor(leftLayer, 1.0f, 0.0f, 0.0f, this);
1123 leftLayer.alpha = 1.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001124 layers.emplace_back(leftLayer);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001125
1126 renderengine::LayerSettings blurLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001127 blurLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001128 blurLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1129 blurLayer.backgroundBlurRadius = blurRadius;
Derek Sollenbergerecb21462021-01-29 16:53:49 -05001130 SourceVariant::fillColor(blurLayer, 0.0f, 0.0f, 1.0f, this);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001131 blurLayer.alpha = 0;
Sally Qi59a9f502021-10-12 18:53:23 +00001132 layers.emplace_back(blurLayer);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001133
Alec Mouric0aae732021-01-12 13:32:18 -08001134 invokeDraw(settings, layers);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001135
Derek Sollenbergerecb21462021-01-29 16:53:49 -05001136 // solid color
1137 expectBufferColor(Rect(0, 0, 1, 1), 255, 0, 0, 255, 0 /* tolerance */);
1138
Derek Sollenbergerb3998372021-02-16 15:16:56 -05001139 if (mRE->supportsBackgroundBlur()) {
1140 // blurred color (downsampling should result in the center color being close to 128)
1141 expectBufferColor(Rect(center - 1, center - 5, center + 1, center + 5), 128, 128, 0, 255,
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001142 50 /* tolerance */);
Derek Sollenbergerb3998372021-02-16 15:16:56 -05001143 }
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001144}
1145
1146template <typename SourceVariant>
Alec Mourie8489fd2021-04-29 16:08:56 -07001147void RenderEngineTest::fillSmallLayerAndBlurBackground() {
1148 auto blurRadius = 50;
1149 renderengine::DisplaySettings settings;
1150 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1151 settings.physicalDisplay = fullscreenRect();
1152 settings.clip = fullscreenRect();
1153
Sally Qi59a9f502021-10-12 18:53:23 +00001154 std::vector<renderengine::LayerSettings> layers;
Alec Mourie8489fd2021-04-29 16:08:56 -07001155
1156 renderengine::LayerSettings backgroundLayer;
1157 backgroundLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1158 backgroundLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1159 SourceVariant::fillColor(backgroundLayer, 1.0f, 0.0f, 0.0f, this);
1160 backgroundLayer.alpha = 1.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001161 layers.push_back(backgroundLayer);
Alec Mourie8489fd2021-04-29 16:08:56 -07001162
1163 renderengine::LayerSettings blurLayer;
1164 blurLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1165 blurLayer.geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f);
1166 blurLayer.backgroundBlurRadius = blurRadius;
1167 SourceVariant::fillColor(blurLayer, 0.0f, 0.0f, 1.0f, this);
1168 blurLayer.alpha = 0;
Sally Qi59a9f502021-10-12 18:53:23 +00001169 layers.push_back(blurLayer);
Alec Mourie8489fd2021-04-29 16:08:56 -07001170
1171 invokeDraw(settings, layers);
1172
1173 // Give a generous tolerance - the blur rectangle is very small and this test is
1174 // mainly concerned with ensuring that there's no device failure.
1175 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT), 255, 0, 0, 255,
1176 40 /* tolerance */);
1177}
1178
1179template <typename SourceVariant>
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001180void RenderEngineTest::overlayCorners() {
1181 renderengine::DisplaySettings settings;
1182 settings.physicalDisplay = fullscreenRect();
1183 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001184 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001185
Sally Qi59a9f502021-10-12 18:53:23 +00001186 std::vector<renderengine::LayerSettings> layersFirst;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001187
1188 renderengine::LayerSettings layerOne;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001189 layerOne.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001190 layerOne.geometry.boundaries =
1191 FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH / 3.0, DEFAULT_DISPLAY_HEIGHT / 3.0);
1192 SourceVariant::fillColor(layerOne, 1.0f, 0.0f, 0.0f, this);
1193 layerOne.alpha = 0.2;
1194
Sally Qi59a9f502021-10-12 18:53:23 +00001195 layersFirst.push_back(layerOne);
Alec Mouric0aae732021-01-12 13:32:18 -08001196 invokeDraw(settings, layersFirst);
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001197 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3), 51, 0, 0, 51);
1198 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3 + 1, DEFAULT_DISPLAY_HEIGHT / 3 + 1,
1199 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1200 0, 0, 0, 0);
1201
Sally Qi59a9f502021-10-12 18:53:23 +00001202 std::vector<renderengine::LayerSettings> layersSecond;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001203 renderengine::LayerSettings layerTwo;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001204 layerTwo.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001205 layerTwo.geometry.boundaries =
1206 FloatRect(DEFAULT_DISPLAY_WIDTH / 3.0, DEFAULT_DISPLAY_HEIGHT / 3.0,
1207 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT);
1208 SourceVariant::fillColor(layerTwo, 0.0f, 1.0f, 0.0f, this);
1209 layerTwo.alpha = 1.0f;
1210
Sally Qi59a9f502021-10-12 18:53:23 +00001211 layersSecond.push_back(layerTwo);
Alec Mouric0aae732021-01-12 13:32:18 -08001212 invokeDraw(settings, layersSecond);
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001213
1214 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3), 0, 0, 0, 0);
1215 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3 + 1, DEFAULT_DISPLAY_HEIGHT / 3 + 1,
1216 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1217 0, 255, 0, 255);
1218}
1219
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001220void RenderEngineTest::fillRedBufferTextureTransform() {
1221 renderengine::DisplaySettings settings;
1222 settings.physicalDisplay = fullscreenRect();
1223 settings.clip = Rect(1, 1);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001224 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001225
Sally Qi59a9f502021-10-12 18:53:23 +00001226 std::vector<renderengine::LayerSettings> layers;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001227
1228 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001229 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001230 // Here will allocate a checker board texture, but transform texture
1231 // coordinates so that only the upper left is applied.
Alec Mouria90a5702021-04-16 16:36:21 +00001232 const auto buf = allocateSourceBuffer(2, 2);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001233
1234 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00001235 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1236 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001237 // Red top left, Green top right, Blue bottom left, Black bottom right
1238 pixels[0] = 255;
1239 pixels[1] = 0;
1240 pixels[2] = 0;
1241 pixels[3] = 255;
1242 pixels[4] = 0;
1243 pixels[5] = 255;
1244 pixels[6] = 0;
1245 pixels[7] = 255;
1246 pixels[8] = 0;
1247 pixels[9] = 0;
1248 pixels[10] = 255;
1249 pixels[11] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00001250 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001251
1252 layer.source.buffer.buffer = buf;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001253 // Transform coordinates to only be inside the red quadrant.
Alec Mouri4049b532021-10-15 20:59:33 -07001254 layer.source.buffer.textureTransform = mat4::scale(vec4(0.2f, 0.2f, 1.f, 1.f));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001255 layer.alpha = 1.0f;
1256 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1257
Sally Qi59a9f502021-10-12 18:53:23 +00001258 layers.push_back(layer);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001259
Alec Mouric0aae732021-01-12 13:32:18 -08001260 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001261}
1262
1263void RenderEngineTest::fillBufferTextureTransform() {
1264 fillRedBufferTextureTransform();
1265 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
1266}
1267
1268void RenderEngineTest::fillRedBufferWithPremultiplyAlpha() {
1269 renderengine::DisplaySettings settings;
1270 settings.physicalDisplay = fullscreenRect();
1271 // Here logical space is 1x1
1272 settings.clip = Rect(1, 1);
1273
Sally Qi59a9f502021-10-12 18:53:23 +00001274 std::vector<renderengine::LayerSettings> layers;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001275
1276 renderengine::LayerSettings layer;
Alec Mouria90a5702021-04-16 16:36:21 +00001277 const auto buf = allocateSourceBuffer(1, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001278
1279 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00001280 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1281 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001282 pixels[0] = 255;
1283 pixels[1] = 0;
1284 pixels[2] = 0;
1285 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00001286 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001287
1288 layer.source.buffer.buffer = buf;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001289 layer.source.buffer.usePremultipliedAlpha = true;
1290 layer.alpha = 0.5f;
1291 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1292
Sally Qi59a9f502021-10-12 18:53:23 +00001293 layers.push_back(layer);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001294
Alec Mouric0aae732021-01-12 13:32:18 -08001295 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001296}
1297
1298void RenderEngineTest::fillBufferWithPremultiplyAlpha() {
1299 fillRedBufferWithPremultiplyAlpha();
1300 expectBufferColor(fullscreenRect(), 128, 0, 0, 128);
1301}
1302
1303void RenderEngineTest::fillRedBufferWithoutPremultiplyAlpha() {
1304 renderengine::DisplaySettings settings;
1305 settings.physicalDisplay = fullscreenRect();
1306 // Here logical space is 1x1
1307 settings.clip = Rect(1, 1);
1308
Sally Qi59a9f502021-10-12 18:53:23 +00001309 std::vector<renderengine::LayerSettings> layers;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001310
1311 renderengine::LayerSettings layer;
Alec Mouria90a5702021-04-16 16:36:21 +00001312 const auto buf = allocateSourceBuffer(1, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001313
1314 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00001315 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1316 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001317 pixels[0] = 255;
1318 pixels[1] = 0;
1319 pixels[2] = 0;
1320 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00001321 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001322
1323 layer.source.buffer.buffer = buf;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001324 layer.source.buffer.usePremultipliedAlpha = false;
1325 layer.alpha = 0.5f;
1326 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1327
Sally Qi59a9f502021-10-12 18:53:23 +00001328 layers.push_back(layer);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001329
Alec Mouric0aae732021-01-12 13:32:18 -08001330 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001331}
1332
1333void RenderEngineTest::fillBufferWithoutPremultiplyAlpha() {
1334 fillRedBufferWithoutPremultiplyAlpha();
wukui16f3c0bb2020-08-05 20:35:29 +08001335 expectBufferColor(fullscreenRect(), 128, 0, 0, 128, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001336}
1337
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001338template <typename SourceVariant>
1339void RenderEngineTest::drawShadow(const renderengine::LayerSettings& castingLayer,
1340 const renderengine::ShadowSettings& shadow,
1341 const ubyte4& casterColor, const ubyte4& backgroundColor) {
1342 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001343 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001344 settings.physicalDisplay = fullscreenRect();
1345 settings.clip = fullscreenRect();
1346
Sally Qi59a9f502021-10-12 18:53:23 +00001347 std::vector<renderengine::LayerSettings> layers;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001348
1349 // add background layer
1350 renderengine::LayerSettings bgLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001351 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001352 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1353 ColorSourceVariant::fillColor(bgLayer, backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1354 backgroundColor.b / 255.0f, this);
1355 bgLayer.alpha = backgroundColor.a / 255.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001356 layers.push_back(bgLayer);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001357
1358 // add shadow layer
1359 renderengine::LayerSettings shadowLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001360 shadowLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001361 shadowLayer.geometry.boundaries = castingLayer.geometry.boundaries;
1362 shadowLayer.alpha = castingLayer.alpha;
1363 shadowLayer.shadow = shadow;
Sally Qi59a9f502021-10-12 18:53:23 +00001364 layers.push_back(shadowLayer);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001365
1366 // add layer casting the shadow
1367 renderengine::LayerSettings layer = castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001368 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001369 SourceVariant::fillColor(layer, casterColor.r / 255.0f, casterColor.g / 255.0f,
1370 casterColor.b / 255.0f, this);
Sally Qi59a9f502021-10-12 18:53:23 +00001371 layers.push_back(layer);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001372
Alec Mouric0aae732021-01-12 13:32:18 -08001373 invokeDraw(settings, layers);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001374}
1375
Alec Mouribd17b3b2020-12-17 11:08:30 -08001376void RenderEngineTest::drawShadowWithoutCaster(const FloatRect& castingBounds,
1377 const renderengine::ShadowSettings& shadow,
1378 const ubyte4& backgroundColor) {
1379 renderengine::DisplaySettings settings;
1380 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1381 settings.physicalDisplay = fullscreenRect();
1382 settings.clip = fullscreenRect();
1383
Sally Qi59a9f502021-10-12 18:53:23 +00001384 std::vector<renderengine::LayerSettings> layers;
Alec Mouribd17b3b2020-12-17 11:08:30 -08001385
1386 // add background layer
1387 renderengine::LayerSettings bgLayer;
1388 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1389 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1390 ColorSourceVariant::fillColor(bgLayer, backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1391 backgroundColor.b / 255.0f, this);
1392 bgLayer.alpha = backgroundColor.a / 255.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001393 layers.push_back(bgLayer);
Alec Mouribd17b3b2020-12-17 11:08:30 -08001394
1395 // add shadow layer
1396 renderengine::LayerSettings shadowLayer;
1397 shadowLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1398 shadowLayer.geometry.boundaries = castingBounds;
Derek Sollenbergerc31985e2021-05-18 16:38:17 -04001399 shadowLayer.skipContentDraw = true;
Alec Mouribd17b3b2020-12-17 11:08:30 -08001400 shadowLayer.alpha = 1.0f;
1401 ColorSourceVariant::fillColor(shadowLayer, 0, 0, 0, this);
1402 shadowLayer.shadow = shadow;
Sally Qi59a9f502021-10-12 18:53:23 +00001403 layers.push_back(shadowLayer);
Alec Mouribd17b3b2020-12-17 11:08:30 -08001404
Alec Mouric0aae732021-01-12 13:32:18 -08001405 invokeDraw(settings, layers);
Alec Mouribd17b3b2020-12-17 11:08:30 -08001406}
1407
Alec Mouri5a493722022-01-26 16:43:02 -08001408void RenderEngineTest::tonemap(ui::Dataspace sourceDataspace, std::function<vec3(vec3)> eotf,
1409 std::function<vec3(vec3, float)> scaleOotf) {
1410 constexpr int32_t kGreyLevels = 256;
1411
1412 const auto rect = Rect(0, 0, kGreyLevels, 1);
1413
1414 constexpr float kMaxLuminance = 750.f;
1415 constexpr float kCurrentLuminanceNits = 500.f;
1416 const renderengine::DisplaySettings display{
1417 .physicalDisplay = rect,
1418 .clip = rect,
1419 .maxLuminance = kMaxLuminance,
1420 .currentLuminanceNits = kCurrentLuminanceNits,
1421 .outputDataspace = ui::Dataspace::DISPLAY_P3,
1422 };
1423
1424 auto buf = std::make_shared<
1425 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07001426 ExternalTexture>(sp<GraphicBuffer>::make(kGreyLevels, 1,
1427 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1428 GRALLOC_USAGE_SW_READ_OFTEN |
1429 GRALLOC_USAGE_SW_WRITE_OFTEN |
1430 GRALLOC_USAGE_HW_RENDER |
1431 GRALLOC_USAGE_HW_TEXTURE,
1432 "input"),
Alec Mouri5a493722022-01-26 16:43:02 -08001433 *mRE,
1434 renderengine::impl::ExternalTexture::Usage::READABLE |
1435 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
1436 ASSERT_EQ(0, buf->getBuffer()->initCheck());
1437 {
1438 uint8_t* pixels;
1439 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1440 reinterpret_cast<void**>(&pixels));
1441
1442 uint8_t color = 0;
1443 for (int32_t j = 0; j < buf->getBuffer()->getHeight(); j++) {
1444 uint8_t* dest = pixels + (buf->getBuffer()->getStride() * j * 4);
1445 for (int32_t i = 0; i < buf->getBuffer()->getWidth(); i++) {
1446 dest[0] = color;
1447 dest[1] = color;
1448 dest[2] = color;
1449 dest[3] = 255;
1450 color++;
1451 dest += 4;
1452 }
1453 }
1454 buf->getBuffer()->unlock();
1455 }
1456
1457 mBuffer = std::make_shared<
1458 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07001459 ExternalTexture>(sp<GraphicBuffer>::make(kGreyLevels, 1,
1460 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1461 GRALLOC_USAGE_SW_READ_OFTEN |
1462 GRALLOC_USAGE_SW_WRITE_OFTEN |
1463 GRALLOC_USAGE_HW_RENDER |
1464 GRALLOC_USAGE_HW_TEXTURE,
1465 "output"),
Alec Mouri5a493722022-01-26 16:43:02 -08001466 *mRE,
1467 renderengine::impl::ExternalTexture::Usage::READABLE |
1468 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
1469 ASSERT_EQ(0, mBuffer->getBuffer()->initCheck());
1470
1471 const renderengine::LayerSettings layer{.geometry.boundaries = rect.toFloatRect(),
1472 .source =
1473 renderengine::PixelSource{
1474 .buffer =
1475 renderengine::Buffer{
1476 .buffer =
1477 std::move(buf),
1478 .usePremultipliedAlpha =
1479 true,
1480 },
1481 },
1482 .alpha = 1.0f,
1483 .sourceDataspace = sourceDataspace};
1484
1485 std::vector<renderengine::LayerSettings> layers{layer};
1486 invokeDraw(display, layers);
1487
1488 ColorSpace displayP3 = ColorSpace::DisplayP3();
1489 ColorSpace bt2020 = ColorSpace::BT2020();
1490
1491 tonemap::Metadata metadata{.displayMaxLuminance = 750.0f};
1492
1493 auto generator = [=](Point location) {
1494 const double normColor = static_cast<double>(location.x) / (kGreyLevels - 1);
1495 const vec3 rgb = vec3(normColor, normColor, normColor);
1496
1497 const vec3 linearRGB = eotf(rgb);
1498
1499 const vec3 xyz = bt2020.getRGBtoXYZ() * linearRGB;
1500
1501 const vec3 scaledXYZ = scaleOotf(xyz, kCurrentLuminanceNits);
Alec Mouri196b0f22022-03-04 22:13:48 +00001502 const auto gains =
Alec Mouri5a493722022-01-26 16:43:02 -08001503 tonemap::getToneMapper()
1504 ->lookupTonemapGain(static_cast<aidl::android::hardware::graphics::common::
1505 Dataspace>(sourceDataspace),
1506 static_cast<aidl::android::hardware::graphics::common::
1507 Dataspace>(
1508 ui::Dataspace::DISPLAY_P3),
Alec Mouri196b0f22022-03-04 22:13:48 +00001509 {tonemap::
1510 Color{.linearRGB =
1511 scaleOotf(linearRGB,
1512 kCurrentLuminanceNits),
1513 .xyz = scaledXYZ}},
Alec Mouri5a493722022-01-26 16:43:02 -08001514 metadata);
Alec Mouri196b0f22022-03-04 22:13:48 +00001515 EXPECT_EQ(1, gains.size());
1516 const double gain = gains.front();
Alec Mouri5a493722022-01-26 16:43:02 -08001517 const vec3 normalizedXYZ = scaledXYZ * gain / metadata.displayMaxLuminance;
1518
1519 const vec3 targetRGB = OETF_sRGB(displayP3.getXYZtoRGB() * normalizedXYZ) * 255;
1520 return ubyte4(static_cast<uint8_t>(targetRGB.r), static_cast<uint8_t>(targetRGB.g),
1521 static_cast<uint8_t>(targetRGB.b), 255);
1522 };
1523
1524 expectBufferColor(Rect(kGreyLevels, 1), generator, 2);
1525}
1526
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001527INSTANTIATE_TEST_SUITE_P(PerRenderEngineType, RenderEngineTest,
Alec Mouric16974e2022-09-13 17:35:48 +00001528 testing::Values(std::make_shared<SkiaGLESRenderEngineFactory>(),
Alec Mouri47bcb072023-08-15 02:02:49 +00001529 std::make_shared<SkiaVkRenderEngineFactory>()));
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001530
1531TEST_P(RenderEngineTest, drawLayers_noLayersToDraw) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001532 if (!GetParam()->typeSupported()) {
1533 GTEST_SKIP();
1534 }
Alec Mouric0aae732021-01-12 13:32:18 -08001535 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001536 drawEmptyLayers();
1537}
1538
Sally Qi1fed86e2022-06-23 15:33:52 -07001539TEST_P(RenderEngineTest, drawLayers_fillRedBufferAndEmptyBuffer) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001540 if (!GetParam()->typeSupported()) {
1541 GTEST_SKIP();
1542 }
Sally Qi1fed86e2022-06-23 15:33:52 -07001543 initializeRenderEngine();
1544 renderengine::DisplaySettings settings;
1545 settings.physicalDisplay = fullscreenRect();
1546 settings.clip = fullscreenRect();
1547 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1548
1549 // add a red layer
1550 renderengine::LayerSettings layerOne{
1551 .geometry.boundaries = fullscreenRect().toFloatRect(),
1552 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
1553 .alpha = 1.f,
1554 };
1555
1556 std::vector<renderengine::LayerSettings> layersFirst{layerOne};
1557 invokeDraw(settings, layersFirst);
1558 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
1559
1560 // re-draw with an empty layer above it, and we get a transparent black one
1561 std::vector<renderengine::LayerSettings> layersSecond;
1562 invokeDraw(settings, layersSecond);
1563 expectBufferColor(fullscreenRect(), 0, 0, 0, 0);
1564}
1565
Ana Krulec07b98df2021-01-07 14:38:40 -08001566TEST_P(RenderEngineTest, drawLayers_withoutBuffers_withColorTransform) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001567 if (!GetParam()->typeSupported()) {
1568 GTEST_SKIP();
1569 }
Alec Mouria90a5702021-04-16 16:36:21 +00001570 initializeRenderEngine();
Ana Krulec07b98df2021-01-07 14:38:40 -08001571
1572 renderengine::DisplaySettings settings;
1573 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1574 settings.physicalDisplay = fullscreenRect();
1575 settings.clip = fullscreenRect();
1576
1577 // 255, 255, 255, 255 is full opaque white.
Alec Mouri4049b532021-10-15 20:59:33 -07001578 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
1579 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Ana Krulec07b98df2021-01-07 14:38:40 -08001580 // Create layer with given color.
1581 renderengine::LayerSettings bgLayer;
1582 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1583 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1584 bgLayer.source.solidColor = half3(backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1585 backgroundColor.b / 255.0f);
1586 bgLayer.alpha = backgroundColor.a / 255.0f;
1587 // Transform the red color.
1588 bgLayer.colorTransform = mat4(-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
1589
Sally Qi59a9f502021-10-12 18:53:23 +00001590 std::vector<renderengine::LayerSettings> layers;
1591 layers.push_back(bgLayer);
Ana Krulec07b98df2021-01-07 14:38:40 -08001592
Alec Mouric0aae732021-01-12 13:32:18 -08001593 invokeDraw(settings, layers);
Ana Krulec07b98df2021-01-07 14:38:40 -08001594
1595 // Expect to see full opaque pixel (with inverted red from the transform).
Alec Mouric0aae732021-01-12 13:32:18 -08001596 expectBufferColor(Rect(0, 0, 10, 10), 0.f, backgroundColor.g, backgroundColor.b,
Ana Krulec07b98df2021-01-07 14:38:40 -08001597 backgroundColor.a);
1598}
1599
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001600TEST_P(RenderEngineTest, drawLayers_nullOutputBuffer) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001601 if (!GetParam()->typeSupported()) {
1602 GTEST_SKIP();
1603 }
Alec Mouric0aae732021-01-12 13:32:18 -08001604 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001605
Alec Mourid43ccab2019-03-13 12:23:45 -07001606 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001607 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Sally Qi59a9f502021-10-12 18:53:23 +00001608 std::vector<renderengine::LayerSettings> layers;
Alec Mourid43ccab2019-03-13 12:23:45 -07001609 renderengine::LayerSettings layer;
1610 layer.geometry.boundaries = fullscreenRect().toFloatRect();
1611 BufferSourceVariant<ForceOpaqueBufferVariant>::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
Sally Qi59a9f502021-10-12 18:53:23 +00001612 layers.push_back(layer);
Patrick Williams2e9748f2022-08-09 22:48:18 +00001613 ftl::Future<FenceResult> future =
Sally Qi4cabdd02021-08-05 16:45:57 -07001614 mRE->drawLayers(settings, layers, nullptr, true, base::unique_fd());
Alec Mourid43ccab2019-03-13 12:23:45 -07001615
Patrick Williams2e9748f2022-08-09 22:48:18 +00001616 ASSERT_TRUE(future.valid());
1617 auto result = future.get();
1618 ASSERT_FALSE(result.ok());
1619 ASSERT_EQ(BAD_VALUE, result.error());
Alec Mourid43ccab2019-03-13 12:23:45 -07001620}
1621
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001622TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001623 if (!GetParam()->typeSupported()) {
1624 GTEST_SKIP();
1625 }
Alec Mouric0aae732021-01-12 13:32:18 -08001626 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001627 fillRedBuffer<ColorSourceVariant>();
1628}
1629
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001630TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001631 if (!GetParam()->typeSupported()) {
1632 GTEST_SKIP();
1633 }
Alec Mouric0aae732021-01-12 13:32:18 -08001634 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001635 fillGreenBuffer<ColorSourceVariant>();
1636}
1637
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001638TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001639 if (!GetParam()->typeSupported()) {
1640 GTEST_SKIP();
1641 }
Alec Mouric0aae732021-01-12 13:32:18 -08001642 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001643 fillBlueBuffer<ColorSourceVariant>();
1644}
1645
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001646TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001647 if (!GetParam()->typeSupported()) {
1648 GTEST_SKIP();
1649 }
Alec Mouric0aae732021-01-12 13:32:18 -08001650 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001651 fillRedTransparentBuffer<ColorSourceVariant>();
1652}
1653
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001654TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001655 if (!GetParam()->typeSupported()) {
1656 GTEST_SKIP();
1657 }
Alec Mouric0aae732021-01-12 13:32:18 -08001658 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001659 fillBufferPhysicalOffset<ColorSourceVariant>();
1660}
1661
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001662TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001663 if (!GetParam()->typeSupported()) {
1664 GTEST_SKIP();
1665 }
Alec Mouric0aae732021-01-12 13:32:18 -08001666 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001667 fillBufferCheckersRotate0<ColorSourceVariant>();
1668}
1669
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001670TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001671 if (!GetParam()->typeSupported()) {
1672 GTEST_SKIP();
1673 }
Alec Mouric0aae732021-01-12 13:32:18 -08001674 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001675 fillBufferCheckersRotate90<ColorSourceVariant>();
1676}
1677
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001678TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001679 if (!GetParam()->typeSupported()) {
1680 GTEST_SKIP();
1681 }
Alec Mouric0aae732021-01-12 13:32:18 -08001682 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001683 fillBufferCheckersRotate180<ColorSourceVariant>();
1684}
1685
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001686TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001687 if (!GetParam()->typeSupported()) {
1688 GTEST_SKIP();
1689 }
Alec Mouric0aae732021-01-12 13:32:18 -08001690 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001691 fillBufferCheckersRotate270<ColorSourceVariant>();
1692}
1693
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001694TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001695 if (!GetParam()->typeSupported()) {
1696 GTEST_SKIP();
1697 }
Alec Mouric0aae732021-01-12 13:32:18 -08001698 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001699 fillBufferLayerTransform<ColorSourceVariant>();
1700}
1701
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001702TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001703 if (!GetParam()->typeSupported()) {
1704 GTEST_SKIP();
1705 }
Alec Mouric0aae732021-01-12 13:32:18 -08001706 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08001707 fillBufferColorTransform<ColorSourceVariant>();
1708}
1709
Sally Qi2019fd22021-11-22 10:19:04 -08001710TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_sourceDataspace) {
1711 const auto& renderEngineFactory = GetParam();
1712 // skip for non color management
Alec Mouri47bcb072023-08-15 02:02:49 +00001713 if (!renderEngineFactory->typeSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001714 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001715 }
1716
1717 initializeRenderEngine();
1718 fillBufferColorTransformAndSourceDataspace<ColorSourceVariant>();
1719}
1720
1721TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_outputDataspace) {
1722 const auto& renderEngineFactory = GetParam();
1723 // skip for non color management
Alec Mouri47bcb072023-08-15 02:02:49 +00001724 if (!renderEngineFactory->typeSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001725 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001726 }
1727
1728 initializeRenderEngine();
1729 fillBufferColorTransformAndOutputDataspace<ColorSourceVariant>();
1730}
1731
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001732TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001733 if (!GetParam()->typeSupported()) {
1734 GTEST_SKIP();
1735 }
Alec Mouric0aae732021-01-12 13:32:18 -08001736 initializeRenderEngine();
Alec Mouri7c94edb2018-12-03 21:23:26 -08001737 fillBufferWithRoundedCorners<ColorSourceVariant>();
1738}
1739
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001740TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001741 if (!GetParam()->typeSupported()) {
1742 GTEST_SKIP();
1743 }
Alec Mouric0aae732021-01-12 13:32:18 -08001744 initializeRenderEngine();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001745 fillBufferColorTransformZeroLayerAlpha<ColorSourceVariant>();
1746}
1747
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001748TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001749 if (!GetParam()->typeSupported()) {
1750 GTEST_SKIP();
1751 }
Alec Mouric0aae732021-01-12 13:32:18 -08001752 initializeRenderEngine();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001753 fillBufferAndBlurBackground<ColorSourceVariant>();
1754}
1755
Alec Mourie8489fd2021-04-29 16:08:56 -07001756TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001757 if (!GetParam()->typeSupported()) {
1758 GTEST_SKIP();
1759 }
Alec Mourie8489fd2021-04-29 16:08:56 -07001760 initializeRenderEngine();
1761 fillSmallLayerAndBlurBackground<ColorSourceVariant>();
1762}
1763
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001764TEST_P(RenderEngineTest, drawLayers_overlayCorners_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001765 if (!GetParam()->typeSupported()) {
1766 GTEST_SKIP();
1767 }
Alec Mouric0aae732021-01-12 13:32:18 -08001768 initializeRenderEngine();
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001769 overlayCorners<ColorSourceVariant>();
1770}
1771
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001772TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001773 if (!GetParam()->typeSupported()) {
1774 GTEST_SKIP();
1775 }
Alec Mouric0aae732021-01-12 13:32:18 -08001776 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001777 fillRedBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1778}
1779
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001780TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001781 if (!GetParam()->typeSupported()) {
1782 GTEST_SKIP();
1783 }
Alec Mouric0aae732021-01-12 13:32:18 -08001784 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001785 fillGreenBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1786}
1787
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001788TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001789 if (!GetParam()->typeSupported()) {
1790 GTEST_SKIP();
1791 }
Alec Mouric0aae732021-01-12 13:32:18 -08001792 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001793 fillBlueBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1794}
1795
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001796TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001797 if (!GetParam()->typeSupported()) {
1798 GTEST_SKIP();
1799 }
Alec Mouric0aae732021-01-12 13:32:18 -08001800 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001801 fillRedTransparentBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1802}
1803
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001804TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001805 if (!GetParam()->typeSupported()) {
1806 GTEST_SKIP();
1807 }
Alec Mouric0aae732021-01-12 13:32:18 -08001808 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001809 fillBufferPhysicalOffset<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1810}
1811
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001812TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001813 if (!GetParam()->typeSupported()) {
1814 GTEST_SKIP();
1815 }
Alec Mouric0aae732021-01-12 13:32:18 -08001816 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001817 fillBufferCheckersRotate0<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1818}
1819
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001820TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001821 if (!GetParam()->typeSupported()) {
1822 GTEST_SKIP();
1823 }
Alec Mouric0aae732021-01-12 13:32:18 -08001824 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001825 fillBufferCheckersRotate90<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1826}
1827
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001828TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001829 if (!GetParam()->typeSupported()) {
1830 GTEST_SKIP();
1831 }
Alec Mouric0aae732021-01-12 13:32:18 -08001832 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001833 fillBufferCheckersRotate180<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1834}
1835
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001836TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001837 if (!GetParam()->typeSupported()) {
1838 GTEST_SKIP();
1839 }
Alec Mouric0aae732021-01-12 13:32:18 -08001840 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001841 fillBufferCheckersRotate270<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1842}
1843
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001844TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001845 if (!GetParam()->typeSupported()) {
1846 GTEST_SKIP();
1847 }
Alec Mouric0aae732021-01-12 13:32:18 -08001848 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001849 fillBufferLayerTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1850}
1851
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001852TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001853 if (!GetParam()->typeSupported()) {
1854 GTEST_SKIP();
1855 }
Alec Mouric0aae732021-01-12 13:32:18 -08001856 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08001857 fillBufferColorTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1858}
1859
Sally Qi2019fd22021-11-22 10:19:04 -08001860TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndSourceDataspace_opaqueBufferSource) {
1861 const auto& renderEngineFactory = GetParam();
1862 // skip for non color management
Alec Mouri47bcb072023-08-15 02:02:49 +00001863 if (!renderEngineFactory->typeSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001864 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001865 }
1866
1867 initializeRenderEngine();
1868 fillBufferColorTransformAndSourceDataspace<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1869}
1870
1871TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndOutputDataspace_opaqueBufferSource) {
1872 const auto& renderEngineFactory = GetParam();
1873 // skip for non color management
Alec Mouri47bcb072023-08-15 02:02:49 +00001874 if (!renderEngineFactory->typeSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001875 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001876 }
1877
1878 initializeRenderEngine();
1879 fillBufferColorTransformAndOutputDataspace<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1880}
1881
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001882TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001883 if (!GetParam()->typeSupported()) {
1884 GTEST_SKIP();
1885 }
Alec Mouric0aae732021-01-12 13:32:18 -08001886 initializeRenderEngine();
Alec Mouri7c94edb2018-12-03 21:23:26 -08001887 fillBufferWithRoundedCorners<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1888}
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001889
Alec Mouric0aae732021-01-12 13:32:18 -08001890TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001891 if (!GetParam()->typeSupported()) {
1892 GTEST_SKIP();
1893 }
Alec Mouric0aae732021-01-12 13:32:18 -08001894 initializeRenderEngine();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001895 fillBufferColorTransformZeroLayerAlpha<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1896}
Alec Mouri7c94edb2018-12-03 21:23:26 -08001897
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001898TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001899 if (!GetParam()->typeSupported()) {
1900 GTEST_SKIP();
1901 }
Alec Mouric0aae732021-01-12 13:32:18 -08001902 initializeRenderEngine();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001903 fillBufferAndBlurBackground<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1904}
1905
Alec Mourie8489fd2021-04-29 16:08:56 -07001906TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001907 if (!GetParam()->typeSupported()) {
1908 GTEST_SKIP();
1909 }
Alec Mourie8489fd2021-04-29 16:08:56 -07001910 initializeRenderEngine();
1911 fillSmallLayerAndBlurBackground<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1912}
1913
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001914TEST_P(RenderEngineTest, drawLayers_overlayCorners_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001915 if (!GetParam()->typeSupported()) {
1916 GTEST_SKIP();
1917 }
Alec Mouric0aae732021-01-12 13:32:18 -08001918 initializeRenderEngine();
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001919 overlayCorners<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1920}
1921
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001922TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001923 if (!GetParam()->typeSupported()) {
1924 GTEST_SKIP();
1925 }
Alec Mouric0aae732021-01-12 13:32:18 -08001926 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001927 fillRedBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1928}
1929
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001930TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001931 if (!GetParam()->typeSupported()) {
1932 GTEST_SKIP();
1933 }
Alec Mouric0aae732021-01-12 13:32:18 -08001934 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001935 fillGreenBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1936}
1937
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001938TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001939 if (!GetParam()->typeSupported()) {
1940 GTEST_SKIP();
1941 }
Alec Mouric0aae732021-01-12 13:32:18 -08001942 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001943 fillBlueBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1944}
1945
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001946TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001947 if (!GetParam()->typeSupported()) {
1948 GTEST_SKIP();
1949 }
Alec Mouric0aae732021-01-12 13:32:18 -08001950 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001951 fillRedTransparentBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1952}
1953
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001954TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001955 if (!GetParam()->typeSupported()) {
1956 GTEST_SKIP();
1957 }
Alec Mouric0aae732021-01-12 13:32:18 -08001958 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001959 fillBufferPhysicalOffset<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1960}
1961
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001962TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001963 if (!GetParam()->typeSupported()) {
1964 GTEST_SKIP();
1965 }
Alec Mouric0aae732021-01-12 13:32:18 -08001966 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001967 fillBufferCheckersRotate0<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1968}
1969
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001970TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001971 if (!GetParam()->typeSupported()) {
1972 GTEST_SKIP();
1973 }
Alec Mouric0aae732021-01-12 13:32:18 -08001974 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001975 fillBufferCheckersRotate90<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1976}
1977
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001978TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001979 if (!GetParam()->typeSupported()) {
1980 GTEST_SKIP();
1981 }
Alec Mouric0aae732021-01-12 13:32:18 -08001982 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001983 fillBufferCheckersRotate180<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1984}
1985
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001986TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001987 if (!GetParam()->typeSupported()) {
1988 GTEST_SKIP();
1989 }
Alec Mouric0aae732021-01-12 13:32:18 -08001990 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001991 fillBufferCheckersRotate270<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1992}
1993
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001994TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001995 if (!GetParam()->typeSupported()) {
1996 GTEST_SKIP();
1997 }
Alec Mouric0aae732021-01-12 13:32:18 -08001998 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001999 fillBufferLayerTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2000}
2001
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002002TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002003 if (!GetParam()->typeSupported()) {
2004 GTEST_SKIP();
2005 }
Alec Mouric0aae732021-01-12 13:32:18 -08002006 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08002007 fillBufferColorTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2008}
2009
Sally Qi2019fd22021-11-22 10:19:04 -08002010TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndSourceDataspace_bufferSource) {
2011 const auto& renderEngineFactory = GetParam();
2012 // skip for non color management
Alec Mouri47bcb072023-08-15 02:02:49 +00002013 if (!renderEngineFactory->typeSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00002014 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08002015 }
2016
2017 initializeRenderEngine();
2018 fillBufferColorTransformAndSourceDataspace<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2019}
2020
2021TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndOutputDataspace_bufferSource) {
2022 const auto& renderEngineFactory = GetParam();
2023 // skip for non color management
Alec Mouri47bcb072023-08-15 02:02:49 +00002024 if (!renderEngineFactory->typeSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00002025 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08002026 }
2027
2028 initializeRenderEngine();
2029 fillBufferColorTransformAndOutputDataspace<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2030}
2031
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002032TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002033 if (!GetParam()->typeSupported()) {
2034 GTEST_SKIP();
2035 }
Alec Mouric0aae732021-01-12 13:32:18 -08002036 initializeRenderEngine();
Alec Mouri7c94edb2018-12-03 21:23:26 -08002037 fillBufferWithRoundedCorners<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2038}
2039
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08002040TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002041 if (!GetParam()->typeSupported()) {
2042 GTEST_SKIP();
2043 }
Alec Mouric0aae732021-01-12 13:32:18 -08002044 initializeRenderEngine();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08002045 fillBufferColorTransformZeroLayerAlpha<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2046}
2047
Nathaniel Nifong53494f32021-04-30 14:05:39 -04002048TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002049 if (!GetParam()->typeSupported()) {
2050 GTEST_SKIP();
2051 }
Alec Mouric0aae732021-01-12 13:32:18 -08002052 initializeRenderEngine();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08002053 fillBufferAndBlurBackground<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2054}
2055
Alec Mourie8489fd2021-04-29 16:08:56 -07002056TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002057 if (!GetParam()->typeSupported()) {
2058 GTEST_SKIP();
2059 }
Alec Mourie8489fd2021-04-29 16:08:56 -07002060 initializeRenderEngine();
2061 fillSmallLayerAndBlurBackground<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2062}
2063
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002064TEST_P(RenderEngineTest, drawLayers_overlayCorners_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002065 if (!GetParam()->typeSupported()) {
2066 GTEST_SKIP();
2067 }
Alec Mouric0aae732021-01-12 13:32:18 -08002068 initializeRenderEngine();
Alec Mourie7d1d4a2019-02-05 01:13:46 +00002069 overlayCorners<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2070}
2071
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002072TEST_P(RenderEngineTest, drawLayers_fillBufferTextureTransform) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002073 if (!GetParam()->typeSupported()) {
2074 GTEST_SKIP();
2075 }
Alec Mouric0aae732021-01-12 13:32:18 -08002076 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002077 fillBufferTextureTransform();
2078}
2079
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002080TEST_P(RenderEngineTest, drawLayers_fillBuffer_premultipliesAlpha) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002081 if (!GetParam()->typeSupported()) {
2082 GTEST_SKIP();
2083 }
Alec Mouric0aae732021-01-12 13:32:18 -08002084 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002085 fillBufferWithPremultiplyAlpha();
2086}
2087
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002088TEST_P(RenderEngineTest, drawLayers_fillBuffer_withoutPremultiplyingAlpha) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002089 if (!GetParam()->typeSupported()) {
2090 GTEST_SKIP();
2091 }
Alec Mouric0aae732021-01-12 13:32:18 -08002092 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002093 fillBufferWithoutPremultiplyAlpha();
2094}
2095
Alec Mouribd17b3b2020-12-17 11:08:30 -08002096TEST_P(RenderEngineTest, drawLayers_fillShadow_castsWithoutCasterLayer) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002097 if (!GetParam()->typeSupported()) {
2098 GTEST_SKIP();
2099 }
Alec Mouric0aae732021-01-12 13:32:18 -08002100 initializeRenderEngine();
Alec Mouribd17b3b2020-12-17 11:08:30 -08002101
Alec Mouri4049b532021-10-15 20:59:33 -07002102 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2103 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Alec Mouribd17b3b2020-12-17 11:08:30 -08002104 const float shadowLength = 5.0f;
2105 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2106 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2107 renderengine::ShadowSettings settings =
2108 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2109 false /* casterIsTranslucent */);
2110
2111 drawShadowWithoutCaster(casterBounds.toFloatRect(), settings, backgroundColor);
2112 expectShadowColorWithoutCaster(casterBounds.toFloatRect(), settings, backgroundColor);
2113}
2114
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002115TEST_P(RenderEngineTest, drawLayers_fillShadow_casterLayerMinSize) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002116 if (!GetParam()->typeSupported()) {
2117 GTEST_SKIP();
2118 }
Alec Mouric0aae732021-01-12 13:32:18 -08002119 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002120
Alec Mouri4049b532021-10-15 20:59:33 -07002121 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2122 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2123 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2124 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002125 const float shadowLength = 5.0f;
2126 Rect casterBounds(1, 1);
2127 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2128 renderengine::LayerSettings castingLayer;
2129 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2130 castingLayer.alpha = 1.0f;
2131 renderengine::ShadowSettings settings =
2132 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2133 false /* casterIsTranslucent */);
2134
2135 drawShadow<ColorSourceVariant>(castingLayer, settings, casterColor, backgroundColor);
2136 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2137}
2138
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002139TEST_P(RenderEngineTest, drawLayers_fillShadow_casterColorLayer) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002140 if (!GetParam()->typeSupported()) {
2141 GTEST_SKIP();
2142 }
Alec Mouric0aae732021-01-12 13:32:18 -08002143 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002144
Alec Mouri4049b532021-10-15 20:59:33 -07002145 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2146 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2147 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2148 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002149 const float shadowLength = 5.0f;
2150 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2151 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2152 renderengine::LayerSettings castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002153 castingLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002154 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2155 castingLayer.alpha = 1.0f;
2156 renderengine::ShadowSettings settings =
2157 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2158 false /* casterIsTranslucent */);
2159
2160 drawShadow<ColorSourceVariant>(castingLayer, settings, casterColor, backgroundColor);
2161 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2162}
2163
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002164TEST_P(RenderEngineTest, drawLayers_fillShadow_casterOpaqueBufferLayer) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002165 if (!GetParam()->typeSupported()) {
2166 GTEST_SKIP();
2167 }
Alec Mouric0aae732021-01-12 13:32:18 -08002168 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002169
Alec Mouri4049b532021-10-15 20:59:33 -07002170 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2171 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2172 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2173 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002174 const float shadowLength = 5.0f;
2175 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2176 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2177 renderengine::LayerSettings castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002178 castingLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002179 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2180 castingLayer.alpha = 1.0f;
2181 renderengine::ShadowSettings settings =
2182 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2183 false /* casterIsTranslucent */);
2184
2185 drawShadow<BufferSourceVariant<ForceOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2186 backgroundColor);
2187 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2188}
2189
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002190TEST_P(RenderEngineTest, drawLayers_fillShadow_casterWithRoundedCorner) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002191 if (!GetParam()->typeSupported()) {
2192 GTEST_SKIP();
2193 }
Alec Mouric0aae732021-01-12 13:32:18 -08002194 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002195
Alec Mouri4049b532021-10-15 20:59:33 -07002196 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2197 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2198 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2199 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002200 const float shadowLength = 5.0f;
2201 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2202 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2203 renderengine::LayerSettings castingLayer;
2204 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002205 castingLayer.geometry.roundedCornersRadius = {3.0f, 3.0f};
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002206 castingLayer.geometry.roundedCornersCrop = casterBounds.toFloatRect();
2207 castingLayer.alpha = 1.0f;
2208 renderengine::ShadowSettings settings =
2209 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2210 false /* casterIsTranslucent */);
2211
2212 drawShadow<BufferSourceVariant<ForceOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2213 backgroundColor);
2214 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2215}
2216
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002217TEST_P(RenderEngineTest, drawLayers_fillShadow_translucentCasterWithAlpha) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002218 if (!GetParam()->typeSupported()) {
2219 GTEST_SKIP();
2220 }
Alec Mouric0aae732021-01-12 13:32:18 -08002221 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002222
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002223 const ubyte4 casterColor(255, 0, 0, 255);
2224 const ubyte4 backgroundColor(255, 255, 255, 255);
2225 const float shadowLength = 5.0f;
2226 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2227 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2228 renderengine::LayerSettings castingLayer;
2229 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2230 castingLayer.alpha = 0.5f;
2231 renderengine::ShadowSettings settings =
2232 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2233 true /* casterIsTranslucent */);
2234
2235 drawShadow<BufferSourceVariant<RelaxOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2236 backgroundColor);
2237
2238 // verify only the background since the shadow will draw behind the caster
2239 const float shadowInset = settings.length * -1.0f;
2240 const Rect casterWithShadow =
2241 Rect(casterBounds).inset(shadowInset, shadowInset, shadowInset, shadowInset);
2242 const Region backgroundRegion = Region(fullscreenRect()).subtractSelf(casterWithShadow);
2243 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
2244 backgroundColor.a);
2245}
2246
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002247TEST_P(RenderEngineTest, cleanupPostRender_cleansUpOnce) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002248 if (!GetParam()->typeSupported()) {
2249 GTEST_SKIP();
2250 }
Alec Mouric0aae732021-01-12 13:32:18 -08002251 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002252
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002253 renderengine::DisplaySettings settings;
2254 settings.physicalDisplay = fullscreenRect();
2255 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002256 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002257
Sally Qi59a9f502021-10-12 18:53:23 +00002258 std::vector<renderengine::LayerSettings> layers;
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002259 renderengine::LayerSettings layer;
2260 layer.geometry.boundaries = fullscreenRect().toFloatRect();
2261 BufferSourceVariant<ForceOpaqueBufferVariant>::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
2262 layer.alpha = 1.0;
Sally Qi59a9f502021-10-12 18:53:23 +00002263 layers.push_back(layer);
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002264
Patrick Williams2e9748f2022-08-09 22:48:18 +00002265 ftl::Future<FenceResult> futureOne =
Sally Qi4cabdd02021-08-05 16:45:57 -07002266 mRE->drawLayers(settings, layers, mBuffer, true, base::unique_fd());
Patrick Williams2e9748f2022-08-09 22:48:18 +00002267 ASSERT_TRUE(futureOne.valid());
2268 auto resultOne = futureOne.get();
2269 ASSERT_TRUE(resultOne.ok());
2270 auto fenceOne = resultOne.value();
Sally Qi4cabdd02021-08-05 16:45:57 -07002271
Patrick Williams2e9748f2022-08-09 22:48:18 +00002272 ftl::Future<FenceResult> futureTwo =
2273 mRE->drawLayers(settings, layers, mBuffer, true, base::unique_fd(fenceOne->dup()));
2274 ASSERT_TRUE(futureTwo.valid());
2275 auto resultTwo = futureTwo.get();
2276 ASSERT_TRUE(resultTwo.ok());
2277 auto fenceTwo = resultTwo.value();
2278 fenceTwo->waitForever(LOG_TAG);
Derek Sollenbergerec411212021-08-25 10:54:47 -04002279
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002280 // Only cleanup the first time.
Ian Elliott1f0911e2022-09-09 16:31:47 -06002281 if (mRE->canSkipPostRenderCleanup()) {
2282 // Skia's Vk backend may keep the texture alive beyond drawLayersInternal, so
2283 // it never gets added to the cleanup list. In those cases, we can skip.
2284 EXPECT_TRUE(GetParam()->type() == renderengine::RenderEngine::RenderEngineType::SKIA_VK);
2285 } else {
2286 mRE->cleanupPostRender();
2287 EXPECT_TRUE(mRE->canSkipPostRenderCleanup());
2288 }
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002289}
2290
Ana Krulecf9a15d92020-12-11 08:35:00 -08002291TEST_P(RenderEngineTest, testRoundedCornersCrop) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002292 if (!GetParam()->typeSupported()) {
2293 GTEST_SKIP();
2294 }
Alec Mouric0aae732021-01-12 13:32:18 -08002295 initializeRenderEngine();
Ana Krulecf9a15d92020-12-11 08:35:00 -08002296
2297 renderengine::DisplaySettings settings;
2298 settings.physicalDisplay = fullscreenRect();
2299 settings.clip = fullscreenRect();
2300 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2301
Sally Qi59a9f502021-10-12 18:53:23 +00002302 std::vector<renderengine::LayerSettings> layers;
Ana Krulecf9a15d92020-12-11 08:35:00 -08002303
2304 renderengine::LayerSettings redLayer;
2305 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2306 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002307 redLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
2308
Ana Krulecf9a15d92020-12-11 08:35:00 -08002309 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2310 // Red background.
2311 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2312 redLayer.alpha = 1.0f;
2313
Sally Qi59a9f502021-10-12 18:53:23 +00002314 layers.push_back(redLayer);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002315
2316 // Green layer with 1/3 size.
2317 renderengine::LayerSettings greenLayer;
2318 greenLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2319 greenLayer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002320 greenLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
Ana Krulecf9a15d92020-12-11 08:35:00 -08002321 // Bottom right corner is not going to be rounded.
2322 greenLayer.geometry.roundedCornersCrop =
2323 Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3, DEFAULT_DISPLAY_HEIGHT,
2324 DEFAULT_DISPLAY_HEIGHT)
2325 .toFloatRect();
2326 greenLayer.source.solidColor = half3(0.0f, 1.0f, 0.0f);
2327 greenLayer.alpha = 1.0f;
2328
Sally Qi59a9f502021-10-12 18:53:23 +00002329 layers.push_back(greenLayer);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002330
Alec Mouric0aae732021-01-12 13:32:18 -08002331 invokeDraw(settings, layers);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002332
2333 // Corners should be ignored...
2334 // Screen size: width is 128, height is 256.
2335 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 0);
2336 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, 0, DEFAULT_DISPLAY_WIDTH, 1), 0, 0, 0, 0);
2337 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT - 1, 1, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
2338 // Bottom right corner is kept out of the clipping, and it's green.
2339 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1,
2340 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
2341 0, 255, 0, 255);
2342}
2343
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002344TEST_P(RenderEngineTest, testRoundedCornersParentCrop) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002345 if (!GetParam()->typeSupported()) {
2346 GTEST_SKIP();
2347 }
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002348 initializeRenderEngine();
2349
2350 renderengine::DisplaySettings settings;
2351 settings.physicalDisplay = fullscreenRect();
2352 settings.clip = fullscreenRect();
2353 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2354
Sally Qi59a9f502021-10-12 18:53:23 +00002355 std::vector<renderengine::LayerSettings> layers;
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002356
2357 renderengine::LayerSettings redLayer;
2358 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2359 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002360 redLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002361 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2362 // Red background.
2363 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2364 redLayer.alpha = 1.0f;
2365
Sally Qi59a9f502021-10-12 18:53:23 +00002366 layers.push_back(redLayer);
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002367
2368 // Green layer with 1/2 size with parent crop rect.
2369 renderengine::LayerSettings greenLayer = redLayer;
2370 greenLayer.geometry.boundaries =
2371 FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT / 2);
2372 greenLayer.source.solidColor = half3(0.0f, 1.0f, 0.0f);
2373
Sally Qi59a9f502021-10-12 18:53:23 +00002374 layers.push_back(greenLayer);
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002375
2376 invokeDraw(settings, layers);
2377
2378 // Due to roundedCornersRadius, the corners are untouched.
2379 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2380 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2381 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2382 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2383
2384 // top middle should be green and the bottom middle red
2385 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, 0), 0, 255, 0, 255);
2386 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0, 255);
2387
2388 // the bottom edge of the green layer should not be rounded
2389 expectBufferColor(Point(0, (DEFAULT_DISPLAY_HEIGHT / 2) - 1), 0, 255, 0, 255);
2390}
2391
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002392TEST_P(RenderEngineTest, testRoundedCornersParentCropSmallBounds) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002393 if (!GetParam()->typeSupported()) {
2394 GTEST_SKIP();
2395 }
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002396 initializeRenderEngine();
2397
2398 renderengine::DisplaySettings settings;
2399 settings.physicalDisplay = fullscreenRect();
2400 settings.clip = fullscreenRect();
2401 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2402
Sally Qi59a9f502021-10-12 18:53:23 +00002403 std::vector<renderengine::LayerSettings> layers;
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002404
2405 renderengine::LayerSettings redLayer;
2406 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2407 redLayer.geometry.boundaries = FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, 32);
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002408 redLayer.geometry.roundedCornersRadius = {64.0f, 64.0f};
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002409 redLayer.geometry.roundedCornersCrop = FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, 128);
2410 // Red background.
2411 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2412 redLayer.alpha = 1.0f;
2413
Sally Qi59a9f502021-10-12 18:53:23 +00002414 layers.push_back(redLayer);
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002415 invokeDraw(settings, layers);
2416
2417 // Due to roundedCornersRadius, the top corners are untouched.
2418 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2419 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2420
2421 // ensure that the entire height of the red layer was clipped by the rounded corners crop.
2422 expectBufferColor(Point(0, 31), 0, 0, 0, 0);
2423 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 31), 0, 0, 0, 0);
2424
2425 // the bottom middle should be red
2426 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, 31), 255, 0, 0, 255);
2427}
2428
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002429TEST_P(RenderEngineTest, testRoundedCornersXY) {
2430 if (GetParam()->type() != renderengine::RenderEngine::RenderEngineType::SKIA_GL) {
2431 GTEST_SKIP();
2432 }
2433
2434 initializeRenderEngine();
2435
2436 renderengine::DisplaySettings settings;
2437 settings.physicalDisplay = fullscreenRect();
2438 settings.clip = fullscreenRect();
2439 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2440
2441 std::vector<renderengine::LayerSettings> layers;
2442
2443 renderengine::LayerSettings redLayer;
2444 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2445 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
2446 redLayer.geometry.roundedCornersRadius = {5.0f, 20.0f};
2447 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2448 // Red background.
2449 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2450 redLayer.alpha = 1.0f;
2451
2452 layers.push_back(redLayer);
2453
2454 invokeDraw(settings, layers);
2455
2456 // Due to roundedCornersRadius, the corners are untouched.
2457 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2458 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2459 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2460 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2461
2462 // Y-axis draws a larger radius, check that its untouched as well
2463 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 5), 0, 0, 0, 0);
2464 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 5), 0, 0, 0, 0);
2465 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 5), 0, 0, 0, 0);
2466 expectBufferColor(Point(0, 5), 0, 0, 0, 0);
2467
2468 // middle should be red
2469 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0, 255);
2470}
2471
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002472TEST_P(RenderEngineTest, testClear) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002473 if (!GetParam()->typeSupported()) {
2474 GTEST_SKIP();
2475 }
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002476 initializeRenderEngine();
2477
2478 const auto rect = fullscreenRect();
2479 const renderengine::DisplaySettings display{
2480 .physicalDisplay = rect,
2481 .clip = rect,
2482 };
2483
2484 const renderengine::LayerSettings redLayer{
2485 .geometry.boundaries = rect.toFloatRect(),
2486 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
2487 .alpha = 1.0f,
2488 };
2489
2490 // This mimics prepareClearClientComposition. This layer should overwrite
2491 // the redLayer, so that the buffer is transparent, rather than red.
2492 const renderengine::LayerSettings clearLayer{
2493 .geometry.boundaries = rect.toFloatRect(),
2494 .source.solidColor = half3(0.0f, 0.0f, 0.0f),
2495 .alpha = 0.0f,
2496 .disableBlending = true,
2497 };
2498
Sally Qi59a9f502021-10-12 18:53:23 +00002499 std::vector<renderengine::LayerSettings> layers{redLayer, clearLayer};
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002500 invokeDraw(display, layers);
2501 expectBufferColor(rect, 0, 0, 0, 0);
2502}
2503
2504TEST_P(RenderEngineTest, testDisableBlendingBuffer) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002505 if (!GetParam()->typeSupported()) {
2506 GTEST_SKIP();
2507 }
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002508 initializeRenderEngine();
2509
2510 const auto rect = Rect(0, 0, 1, 1);
2511 const renderengine::DisplaySettings display{
2512 .physicalDisplay = rect,
2513 .clip = rect,
2514 };
2515
2516 const renderengine::LayerSettings redLayer{
2517 .geometry.boundaries = rect.toFloatRect(),
2518 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
2519 .alpha = 1.0f,
2520 };
2521
2522 // The next layer will overwrite redLayer with a GraphicBuffer that is green
2523 // applied with a translucent alpha.
Alec Mouria90a5702021-04-16 16:36:21 +00002524 const auto buf = allocateSourceBuffer(1, 1);
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002525 {
2526 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00002527 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2528 reinterpret_cast<void**>(&pixels));
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002529 pixels[0] = 0;
2530 pixels[1] = 255;
2531 pixels[2] = 0;
2532 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00002533 buf->getBuffer()->unlock();
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002534 }
2535
2536 const renderengine::LayerSettings greenLayer{
2537 .geometry.boundaries = rect.toFloatRect(),
2538 .source =
2539 renderengine::PixelSource{
2540 .buffer =
2541 renderengine::Buffer{
2542 .buffer = buf,
2543 .usePremultipliedAlpha = true,
2544 },
2545 },
2546 .alpha = 0.5f,
2547 .disableBlending = true,
2548 };
2549
Sally Qi59a9f502021-10-12 18:53:23 +00002550 std::vector<renderengine::LayerSettings> layers{redLayer, greenLayer};
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002551 invokeDraw(display, layers);
2552 expectBufferColor(rect, 0, 128, 0, 128);
2553}
2554
Tianhao Yao67dd7122022-02-22 17:48:33 +00002555TEST_P(RenderEngineTest, testBorder) {
2556 if (GetParam()->type() != renderengine::RenderEngine::RenderEngineType::SKIA_GL) {
2557 GTEST_SKIP();
2558 }
2559
Tianhao Yao67dd7122022-02-22 17:48:33 +00002560 initializeRenderEngine();
2561
2562 const ui::Dataspace dataspace = ui::Dataspace::V0_SRGB;
2563
2564 const auto displayRect = Rect(1080, 2280);
2565 renderengine::DisplaySettings display{
2566 .physicalDisplay = displayRect,
2567 .clip = displayRect,
2568 .outputDataspace = dataspace,
2569 };
2570 display.borderInfoList.clear();
2571 renderengine::BorderRenderInfo info;
2572 info.combinedRegion = Region(Rect(99, 99, 199, 199));
Tianhao Yao10cea3c2022-03-30 01:37:22 +00002573 info.width = 20.0f;
2574 info.color = half4{1.0f, 128.0f / 255.0f, 0.0f, 1.0f};
Tianhao Yao67dd7122022-02-22 17:48:33 +00002575 display.borderInfoList.emplace_back(info);
2576
2577 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2578 const renderengine::LayerSettings greenLayer{
2579 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2580 .source =
2581 renderengine::PixelSource{
2582 .buffer =
2583 renderengine::Buffer{
2584 .buffer = greenBuffer,
2585 .usePremultipliedAlpha = true,
2586 },
2587 },
2588 .alpha = 1.0f,
2589 .sourceDataspace = dataspace,
2590 .whitePointNits = 200.f,
2591 };
2592
2593 std::vector<renderengine::LayerSettings> layers;
2594 layers.emplace_back(greenLayer);
2595 invokeDraw(display, layers);
2596
2597 expectBufferColor(Rect(99, 99, 101, 101), 255, 128, 0, 255, 1);
2598}
2599
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002600TEST_P(RenderEngineTest, testDimming) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002601 if (!GetParam()->typeSupported()) {
2602 GTEST_SKIP();
2603 }
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002604 initializeRenderEngine();
2605
Alec Mouri85065692022-03-18 00:58:26 +00002606 const ui::Dataspace dataspace = ui::Dataspace::V0_SRGB_LINEAR;
2607
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002608 const auto displayRect = Rect(3, 1);
2609 const renderengine::DisplaySettings display{
2610 .physicalDisplay = displayRect,
2611 .clip = displayRect,
Alec Mouri85065692022-03-18 00:58:26 +00002612 .outputDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002613 .targetLuminanceNits = 1000.f,
2614 };
2615
2616 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2617 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2618 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2619
2620 const renderengine::LayerSettings greenLayer{
2621 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2622 .source =
2623 renderengine::PixelSource{
2624 .buffer =
2625 renderengine::Buffer{
2626 .buffer = greenBuffer,
2627 .usePremultipliedAlpha = true,
2628 },
2629 },
2630 .alpha = 1.0f,
Alec Mouri85065692022-03-18 00:58:26 +00002631 .sourceDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002632 .whitePointNits = 200.f,
2633 };
2634
2635 const renderengine::LayerSettings blueLayer{
2636 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2637 .source =
2638 renderengine::PixelSource{
2639 .buffer =
2640 renderengine::Buffer{
2641 .buffer = blueBuffer,
2642 .usePremultipliedAlpha = true,
2643 },
2644 },
2645 .alpha = 1.0f,
Alec Mouri85065692022-03-18 00:58:26 +00002646 .sourceDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002647 .whitePointNits = 1000.f / 51.f,
2648 };
2649
2650 const renderengine::LayerSettings redLayer{
2651 .geometry.boundaries = FloatRect(2.f, 0.f, 3.f, 1.f),
2652 .source =
2653 renderengine::PixelSource{
2654 .buffer =
2655 renderengine::Buffer{
2656 .buffer = redBuffer,
2657 .usePremultipliedAlpha = true,
2658 },
2659 },
2660 .alpha = 1.0f,
Alec Mouri85065692022-03-18 00:58:26 +00002661 .sourceDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002662 // When the white point is not set for a layer, just ignore it and treat it as the same
2663 // as the max layer
2664 .whitePointNits = -1.f,
2665 };
2666
2667 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer, redLayer};
2668 invokeDraw(display, layers);
2669
2670 expectBufferColor(Rect(1, 1), 0, 51, 0, 255, 1);
2671 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 5, 255, 1);
2672 expectBufferColor(Rect(2, 0, 3, 1), 51, 0, 0, 255, 1);
2673}
2674
Alec Mouri85065692022-03-18 00:58:26 +00002675TEST_P(RenderEngineTest, testDimming_inGammaSpace) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002676 if (!GetParam()->typeSupported()) {
2677 GTEST_SKIP();
2678 }
Alec Mouri85065692022-03-18 00:58:26 +00002679 initializeRenderEngine();
2680
2681 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2682 ui::Dataspace::TRANSFER_GAMMA2_2 |
2683 ui::Dataspace::RANGE_FULL);
2684
2685 const auto displayRect = Rect(3, 1);
2686 const renderengine::DisplaySettings display{
2687 .physicalDisplay = displayRect,
2688 .clip = displayRect,
2689 .outputDataspace = dataspace,
2690 .targetLuminanceNits = 1000.f,
2691 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2692 };
2693
2694 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2695 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2696 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2697
2698 const renderengine::LayerSettings greenLayer{
2699 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2700 .source =
2701 renderengine::PixelSource{
2702 .buffer =
2703 renderengine::Buffer{
2704 .buffer = greenBuffer,
2705 .usePremultipliedAlpha = true,
2706 },
2707 },
2708 .alpha = 1.0f,
2709 .sourceDataspace = dataspace,
2710 .whitePointNits = 200.f,
2711 };
2712
2713 const renderengine::LayerSettings blueLayer{
2714 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2715 .source =
2716 renderengine::PixelSource{
2717 .buffer =
2718 renderengine::Buffer{
2719 .buffer = blueBuffer,
2720 .usePremultipliedAlpha = true,
2721 },
2722 },
2723 .alpha = 1.0f,
2724 .sourceDataspace = dataspace,
2725 .whitePointNits = 1000.f / 51.f,
2726 };
2727
2728 const renderengine::LayerSettings redLayer{
2729 .geometry.boundaries = FloatRect(2.f, 0.f, 3.f, 1.f),
2730 .source =
2731 renderengine::PixelSource{
2732 .buffer =
2733 renderengine::Buffer{
2734 .buffer = redBuffer,
2735 .usePremultipliedAlpha = true,
2736 },
2737 },
2738 .alpha = 1.0f,
2739 .sourceDataspace = dataspace,
2740 // When the white point is not set for a layer, just ignore it and treat it as the same
2741 // as the max layer
2742 .whitePointNits = -1.f,
2743 };
2744
2745 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer, redLayer};
2746 invokeDraw(display, layers);
2747
2748 expectBufferColor(Rect(1, 1), 0, 122, 0, 255, 1);
2749 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 42, 255, 1);
2750 expectBufferColor(Rect(2, 0, 3, 1), 122, 0, 0, 255, 1);
2751}
2752
Alec Mouri9bcd1d12022-04-21 22:16:56 +00002753TEST_P(RenderEngineTest, testDimming_inGammaSpace_withDisplayColorTransform) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002754 if (!GetParam()->typeSupported()) {
2755 GTEST_SKIP();
2756 }
Alec Mouri9bcd1d12022-04-21 22:16:56 +00002757 initializeRenderEngine();
2758
2759 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2760 ui::Dataspace::TRANSFER_GAMMA2_2 |
2761 ui::Dataspace::RANGE_FULL);
2762
2763 const auto displayRect = Rect(3, 1);
2764 const renderengine::DisplaySettings display{
2765 .physicalDisplay = displayRect,
2766 .clip = displayRect,
2767 .outputDataspace = dataspace,
2768 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
2769 .targetLuminanceNits = 1000.f,
2770 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2771 };
2772
2773 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2774 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2775 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2776
2777 const renderengine::LayerSettings greenLayer{
2778 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2779 .source =
2780 renderengine::PixelSource{
2781 .buffer =
2782 renderengine::Buffer{
2783 .buffer = greenBuffer,
2784 .usePremultipliedAlpha = true,
2785 },
2786 },
2787 .alpha = 1.0f,
2788 .sourceDataspace = dataspace,
2789 .whitePointNits = 200.f,
2790 };
2791
2792 const renderengine::LayerSettings redLayer{
2793 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2794 .source =
2795 renderengine::PixelSource{
2796 .buffer =
2797 renderengine::Buffer{
2798 .buffer = redBuffer,
2799 .usePremultipliedAlpha = true,
2800 },
2801 },
2802 .alpha = 1.0f,
2803 .sourceDataspace = dataspace,
2804 // When the white point is not set for a layer, just ignore it and treat it as the same
2805 // as the max layer
2806 .whitePointNits = -1.f,
2807 };
2808
2809 std::vector<renderengine::LayerSettings> layers{greenLayer, redLayer};
2810 invokeDraw(display, layers);
2811
2812 expectBufferColor(Rect(1, 1), 0, 0, 0, 255, 1);
2813 expectBufferColor(Rect(1, 0, 2, 1), 0, 122, 0, 255, 1);
2814}
2815
2816TEST_P(RenderEngineTest, testDimming_inGammaSpace_withDisplayColorTransform_deviceHandles) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002817 if (!GetParam()->typeSupported()) {
2818 GTEST_SKIP();
2819 }
Alec Mouri9bcd1d12022-04-21 22:16:56 +00002820 initializeRenderEngine();
2821
2822 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2823 ui::Dataspace::TRANSFER_GAMMA2_2 |
2824 ui::Dataspace::RANGE_FULL);
2825
2826 const auto displayRect = Rect(3, 1);
2827 const renderengine::DisplaySettings display{
2828 .physicalDisplay = displayRect,
2829 .clip = displayRect,
2830 .outputDataspace = dataspace,
2831 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
2832 .deviceHandlesColorTransform = true,
2833 .targetLuminanceNits = 1000.f,
2834 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2835 };
2836
2837 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2838 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2839 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2840
2841 const renderengine::LayerSettings greenLayer{
2842 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2843 .source =
2844 renderengine::PixelSource{
2845 .buffer =
2846 renderengine::Buffer{
2847 .buffer = greenBuffer,
2848 .usePremultipliedAlpha = true,
2849 },
2850 },
2851 .alpha = 1.0f,
2852 .sourceDataspace = dataspace,
2853 .whitePointNits = 200.f,
2854 };
2855
2856 const renderengine::LayerSettings redLayer{
2857 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2858 .source =
2859 renderengine::PixelSource{
2860 .buffer =
2861 renderengine::Buffer{
2862 .buffer = redBuffer,
2863 .usePremultipliedAlpha = true,
2864 },
2865 },
2866 .alpha = 1.0f,
2867 .sourceDataspace = dataspace,
2868 // When the white point is not set for a layer, just ignore it and treat it as the same
2869 // as the max layer
2870 .whitePointNits = -1.f,
2871 };
2872
2873 std::vector<renderengine::LayerSettings> layers{greenLayer, redLayer};
2874 invokeDraw(display, layers);
2875
2876 expectBufferColor(Rect(1, 1), 0, 122, 0, 255, 1);
2877 expectBufferColor(Rect(1, 0, 2, 1), 122, 0, 0, 255, 1);
2878}
2879
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002880TEST_P(RenderEngineTest, testDimming_withoutTargetLuminance) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002881 if (!GetParam()->typeSupported()) {
2882 GTEST_SKIP();
2883 }
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002884 initializeRenderEngine();
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002885
2886 const auto displayRect = Rect(2, 1);
2887 const renderengine::DisplaySettings display{
2888 .physicalDisplay = displayRect,
2889 .clip = displayRect,
2890 .outputDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2891 .targetLuminanceNits = -1.f,
2892 };
2893
2894 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2895 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2896
2897 const renderengine::LayerSettings greenLayer{
2898 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2899 .source =
2900 renderengine::PixelSource{
2901 .buffer =
2902 renderengine::Buffer{
2903 .buffer = greenBuffer,
2904 .usePremultipliedAlpha = true,
2905 },
2906 },
2907 .alpha = 1.0f,
2908 .sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2909 .whitePointNits = 200.f,
2910 };
2911
2912 const renderengine::LayerSettings blueLayer{
2913 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2914 .source =
2915 renderengine::PixelSource{
2916 .buffer =
2917 renderengine::Buffer{
2918 .buffer = blueBuffer,
2919 .usePremultipliedAlpha = true,
2920 },
2921 },
2922 .alpha = 1.0f,
2923 .sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2924 .whitePointNits = 1000.f,
2925 };
2926
2927 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer};
2928 invokeDraw(display, layers);
2929
2930 expectBufferColor(Rect(1, 1), 0, 51, 0, 255, 1);
2931 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 255, 255);
2932}
2933
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002934TEST_P(RenderEngineTest, test_isOpaque) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002935 if (!GetParam()->typeSupported()) {
2936 GTEST_SKIP();
2937 }
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002938 initializeRenderEngine();
2939
2940 const auto rect = Rect(0, 0, 1, 1);
2941 const renderengine::DisplaySettings display{
2942 .physicalDisplay = rect,
2943 .clip = rect,
2944 .outputDataspace = ui::Dataspace::DISPLAY_P3,
2945 };
2946
2947 // Create an unpremul buffer that is green with no alpha. Using isOpaque
2948 // should make the green show.
2949 const auto buf = allocateSourceBuffer(1, 1);
2950 {
2951 uint8_t* pixels;
2952 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2953 reinterpret_cast<void**>(&pixels));
2954 pixels[0] = 0;
2955 pixels[1] = 255;
2956 pixels[2] = 0;
2957 pixels[3] = 0;
2958 buf->getBuffer()->unlock();
2959 }
2960
2961 const renderengine::LayerSettings greenLayer{
2962 .geometry.boundaries = rect.toFloatRect(),
2963 .source =
2964 renderengine::PixelSource{
2965 .buffer =
2966 renderengine::Buffer{
2967 .buffer = buf,
2968 // Although the pixels are not
2969 // premultiplied in practice, this
2970 // matches the input we see.
2971 .usePremultipliedAlpha = true,
2972 .isOpaque = true,
2973 },
2974 },
2975 .alpha = 1.0f,
2976 };
2977
Sally Qi59a9f502021-10-12 18:53:23 +00002978 std::vector<renderengine::LayerSettings> layers{greenLayer};
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002979 invokeDraw(display, layers);
2980
Alec Mouri47bcb072023-08-15 02:02:49 +00002981 expectBufferColor(rect, 117, 251, 76, 255);
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002982}
Alec Mouri4049b532021-10-15 20:59:33 -07002983
Alec Mouri4049b532021-10-15 20:59:33 -07002984TEST_P(RenderEngineTest, test_tonemapPQMatches) {
Alec Mouri47bcb072023-08-15 02:02:49 +00002985 if (!GetParam()->typeSupported()) {
Alec Mouri5a493722022-01-26 16:43:02 -08002986 GTEST_SKIP();
Alec Mouri4049b532021-10-15 20:59:33 -07002987 }
2988
Alec Mouri4049b532021-10-15 20:59:33 -07002989 initializeRenderEngine();
2990
Alec Mouri5a493722022-01-26 16:43:02 -08002991 tonemap(
2992 static_cast<ui::Dataspace>(HAL_DATASPACE_STANDARD_BT2020 |
2993 HAL_DATASPACE_TRANSFER_ST2084 | HAL_DATASPACE_RANGE_FULL),
2994 [](vec3 color) { return EOTF_PQ(color); },
2995 [](vec3 color, float) {
2996 static constexpr float kMaxPQLuminance = 10000.f;
2997 return color * kMaxPQLuminance;
2998 });
2999}
Alec Mouri4049b532021-10-15 20:59:33 -07003000
Alec Mouri5a493722022-01-26 16:43:02 -08003001TEST_P(RenderEngineTest, test_tonemapHLGMatches) {
Alec Mouri47bcb072023-08-15 02:02:49 +00003002 if (!GetParam()->typeSupported()) {
Alec Mouri5a493722022-01-26 16:43:02 -08003003 GTEST_SKIP();
Alec Mouri4049b532021-10-15 20:59:33 -07003004 }
3005
Alec Mouri5a493722022-01-26 16:43:02 -08003006 initializeRenderEngine();
Alec Mouri4049b532021-10-15 20:59:33 -07003007
Alec Mouri5a493722022-01-26 16:43:02 -08003008 tonemap(
3009 static_cast<ui::Dataspace>(HAL_DATASPACE_STANDARD_BT2020 | HAL_DATASPACE_TRANSFER_HLG |
3010 HAL_DATASPACE_RANGE_FULL),
3011 [](vec3 color) { return EOTF_HLG(color); },
3012 [](vec3 color, float currentLuminaceNits) {
3013 static constexpr float kMaxHLGLuminance = 1000.f;
Alec Mouri7a577452022-03-04 23:41:38 +00003014 return color * kMaxHLGLuminance;
Alec Mouri5a493722022-01-26 16:43:02 -08003015 });
Alec Mouri4049b532021-10-15 20:59:33 -07003016}
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -05003017
3018TEST_P(RenderEngineTest, r8_behaves_as_mask) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003019 if (!GetParam()->typeSupported()) {
3020 GTEST_SKIP();
3021 }
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -05003022 initializeRenderEngine();
3023
3024 const auto r8Buffer = allocateR8Buffer(2, 1);
3025 if (!r8Buffer) {
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003026 GTEST_SKIP() << "Test is only necessary on devices that support r8";
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -05003027 return;
3028 }
3029 {
3030 uint8_t* pixels;
3031 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
3032 reinterpret_cast<void**>(&pixels));
3033 // This will be drawn on top of a green buffer. We'll verify that 255
3034 // results in keeping the original green and 0 results in black.
3035 pixels[0] = 0;
3036 pixels[1] = 255;
3037 r8Buffer->getBuffer()->unlock();
3038 }
3039
3040 const auto rect = Rect(0, 0, 2, 1);
3041 const renderengine::DisplaySettings display{
3042 .physicalDisplay = rect,
3043 .clip = rect,
3044 .outputDataspace = ui::Dataspace::SRGB,
3045 };
3046
3047 const auto greenBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(0, 255, 0, 255));
3048 const renderengine::LayerSettings greenLayer{
3049 .geometry.boundaries = rect.toFloatRect(),
3050 .source =
3051 renderengine::PixelSource{
3052 .buffer =
3053 renderengine::Buffer{
3054 .buffer = greenBuffer,
3055 },
3056 },
3057 .alpha = 1.0f,
3058 };
3059 const renderengine::LayerSettings r8Layer{
3060 .geometry.boundaries = rect.toFloatRect(),
3061 .source =
3062 renderengine::PixelSource{
3063 .buffer =
3064 renderengine::Buffer{
3065 .buffer = r8Buffer,
3066 },
3067 },
3068 .alpha = 1.0f,
3069 };
3070
3071 std::vector<renderengine::LayerSettings> layers{greenLayer, r8Layer};
3072 invokeDraw(display, layers);
3073
3074 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 255);
3075 expectBufferColor(Rect(1, 0, 2, 1), 0, 255, 0, 255);
3076}
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003077
3078TEST_P(RenderEngineTest, r8_respects_color_transform) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003079 if (!GetParam()->typeSupported()) {
3080 GTEST_SKIP();
3081 }
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003082 initializeRenderEngine();
3083
3084 const auto r8Buffer = allocateR8Buffer(2, 1);
3085 if (!r8Buffer) {
3086 GTEST_SKIP() << "Test is only necessary on devices that support r8";
3087 return;
3088 }
3089 {
3090 uint8_t* pixels;
3091 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
3092 reinterpret_cast<void**>(&pixels));
3093 pixels[0] = 0;
3094 pixels[1] = 255;
3095 r8Buffer->getBuffer()->unlock();
3096 }
3097
3098 const auto rect = Rect(0, 0, 2, 1);
3099 const renderengine::DisplaySettings display{
3100 .physicalDisplay = rect,
3101 .clip = rect,
3102 .outputDataspace = ui::Dataspace::SRGB,
3103 // Verify that the R8 layer respects the color transform when
3104 // deviceHandlesColorTransform is false. This transform converts
3105 // pure red to pure green. That will occur when the R8 buffer is
3106 // 255. When the R8 buffer is 0, it will still change to black, as
3107 // with r8_behaves_as_mask.
Alec Mouri9bcd1d12022-04-21 22:16:56 +00003108 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003109 .deviceHandlesColorTransform = false,
3110 };
3111
3112 const auto redBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(255, 0, 0, 255));
3113 const renderengine::LayerSettings redLayer{
3114 .geometry.boundaries = rect.toFloatRect(),
3115 .source =
3116 renderengine::PixelSource{
3117 .buffer =
3118 renderengine::Buffer{
3119 .buffer = redBuffer,
3120 },
3121 },
3122 .alpha = 1.0f,
3123 };
3124 const renderengine::LayerSettings r8Layer{
3125 .geometry.boundaries = rect.toFloatRect(),
3126 .source =
3127 renderengine::PixelSource{
3128 .buffer =
3129 renderengine::Buffer{
3130 .buffer = r8Buffer,
3131 },
3132 },
3133 .alpha = 1.0f,
3134 };
3135
3136 std::vector<renderengine::LayerSettings> layers{redLayer, r8Layer};
3137 invokeDraw(display, layers);
3138
3139 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 255);
3140 expectBufferColor(Rect(1, 0, 2, 1), 0, 255, 0, 255);
3141}
3142
3143TEST_P(RenderEngineTest, r8_respects_color_transform_when_device_handles) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003144 if (!GetParam()->typeSupported()) {
3145 GTEST_SKIP();
3146 }
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003147 initializeRenderEngine();
3148
3149 const auto r8Buffer = allocateR8Buffer(2, 1);
3150 if (!r8Buffer) {
3151 GTEST_SKIP() << "Test is only necessary on devices that support r8";
3152 return;
3153 }
3154 {
3155 uint8_t* pixels;
3156 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
3157 reinterpret_cast<void**>(&pixels));
3158 pixels[0] = 0;
3159 pixels[1] = 255;
3160 r8Buffer->getBuffer()->unlock();
3161 }
3162
3163 const auto rect = Rect(0, 0, 2, 1);
3164 const renderengine::DisplaySettings display{
3165 .physicalDisplay = rect,
3166 .clip = rect,
3167 .outputDataspace = ui::Dataspace::SRGB,
3168 // If deviceHandlesColorTransform is true, pixels where the A8
3169 // buffer is opaque are unaffected. If the colorTransform is
3170 // invertible, pixels where the A8 buffer are transparent have the
3171 // inverse applied to them so that the DPU will convert them back to
3172 // black. Test with an arbitrary, invertible matrix.
3173 .colorTransform = mat4(1, 0, 0, 2,
3174 3, 1, 2, 5,
3175 0, 5, 3, 0,
3176 0, 1, 0, 2),
3177 .deviceHandlesColorTransform = true,
3178 };
3179
3180 const auto redBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(255, 0, 0, 255));
3181 const renderengine::LayerSettings redLayer{
3182 .geometry.boundaries = rect.toFloatRect(),
3183 .source =
3184 renderengine::PixelSource{
3185 .buffer =
3186 renderengine::Buffer{
3187 .buffer = redBuffer,
3188 },
3189 },
3190 .alpha = 1.0f,
3191 };
3192 const renderengine::LayerSettings r8Layer{
3193 .geometry.boundaries = rect.toFloatRect(),
3194 .source =
3195 renderengine::PixelSource{
3196 .buffer =
3197 renderengine::Buffer{
3198 .buffer = r8Buffer,
3199 },
3200 },
3201 .alpha = 1.0f,
3202 };
3203
3204 std::vector<renderengine::LayerSettings> layers{redLayer, r8Layer};
3205 invokeDraw(display, layers);
3206
3207 expectBufferColor(Rect(1, 0, 2, 1), 255, 0, 0, 255); // Still red.
3208 expectBufferColor(Rect(0, 0, 1, 1), 0, 70, 0, 255);
3209}
Leon Scroggins III45be9182022-04-27 10:37:11 -04003210
3211TEST_P(RenderEngineTest, primeShaderCache) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003212 if (!GetParam()->typeSupported()) {
3213 GTEST_SKIP();
3214 }
Leon Scroggins III45be9182022-04-27 10:37:11 -04003215 initializeRenderEngine();
3216
3217 auto fut = mRE->primeCache();
3218 if (fut.valid()) {
3219 fut.wait();
3220 }
3221
Alec Mouri47bcb072023-08-15 02:02:49 +00003222 static constexpr int kMinimumExpectedShadersCompiled = 60;
Leon Scroggins III45be9182022-04-27 10:37:11 -04003223 ASSERT_GT(static_cast<skia::SkiaGLRenderEngine*>(mRE.get())->reportShadersCompiled(),
Alec Mouri47bcb072023-08-15 02:02:49 +00003224 kMinimumExpectedShadersCompiled);
Leon Scroggins III45be9182022-04-27 10:37:11 -04003225}
Derek Sollenbergerd3f60652021-06-11 15:34:36 -04003226} // namespace renderengine
Alec Mouri6e57f682018-09-29 20:45:08 -07003227} // namespace android
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08003228
3229// TODO(b/129481165): remove the #pragma below and fix conversion issues
Marin Shalamanovbed7fd32020-12-21 20:02:20 +01003230#pragma clang diagnostic pop // ignored "-Wconversion -Wextra"