blob: 7dde71632bd3be2233551c9af2b1843a5fcb74ea [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 =
Alec Mourif29700f2023-08-17 21:53:31 +0000493 mRE->drawLayers(settings, layers, mBuffer, 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);
Alec Mourif29700f2023-08-17 21:53:31 +00001613 ftl::Future<FenceResult> future = mRE->drawLayers(settings, layers, nullptr, base::unique_fd());
Alec Mourid43ccab2019-03-13 12:23:45 -07001614
Patrick Williams2e9748f2022-08-09 22:48:18 +00001615 ASSERT_TRUE(future.valid());
1616 auto result = future.get();
1617 ASSERT_FALSE(result.ok());
1618 ASSERT_EQ(BAD_VALUE, result.error());
Alec Mourid43ccab2019-03-13 12:23:45 -07001619}
1620
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001621TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001622 if (!GetParam()->typeSupported()) {
1623 GTEST_SKIP();
1624 }
Alec Mouric0aae732021-01-12 13:32:18 -08001625 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001626 fillRedBuffer<ColorSourceVariant>();
1627}
1628
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001629TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001630 if (!GetParam()->typeSupported()) {
1631 GTEST_SKIP();
1632 }
Alec Mouric0aae732021-01-12 13:32:18 -08001633 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001634 fillGreenBuffer<ColorSourceVariant>();
1635}
1636
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001637TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001638 if (!GetParam()->typeSupported()) {
1639 GTEST_SKIP();
1640 }
Alec Mouric0aae732021-01-12 13:32:18 -08001641 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001642 fillBlueBuffer<ColorSourceVariant>();
1643}
1644
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001645TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001646 if (!GetParam()->typeSupported()) {
1647 GTEST_SKIP();
1648 }
Alec Mouric0aae732021-01-12 13:32:18 -08001649 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001650 fillRedTransparentBuffer<ColorSourceVariant>();
1651}
1652
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001653TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001654 if (!GetParam()->typeSupported()) {
1655 GTEST_SKIP();
1656 }
Alec Mouric0aae732021-01-12 13:32:18 -08001657 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001658 fillBufferPhysicalOffset<ColorSourceVariant>();
1659}
1660
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001661TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001662 if (!GetParam()->typeSupported()) {
1663 GTEST_SKIP();
1664 }
Alec Mouric0aae732021-01-12 13:32:18 -08001665 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001666 fillBufferCheckersRotate0<ColorSourceVariant>();
1667}
1668
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001669TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001670 if (!GetParam()->typeSupported()) {
1671 GTEST_SKIP();
1672 }
Alec Mouric0aae732021-01-12 13:32:18 -08001673 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001674 fillBufferCheckersRotate90<ColorSourceVariant>();
1675}
1676
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001677TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001678 if (!GetParam()->typeSupported()) {
1679 GTEST_SKIP();
1680 }
Alec Mouric0aae732021-01-12 13:32:18 -08001681 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001682 fillBufferCheckersRotate180<ColorSourceVariant>();
1683}
1684
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001685TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001686 if (!GetParam()->typeSupported()) {
1687 GTEST_SKIP();
1688 }
Alec Mouric0aae732021-01-12 13:32:18 -08001689 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001690 fillBufferCheckersRotate270<ColorSourceVariant>();
1691}
1692
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001693TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001694 if (!GetParam()->typeSupported()) {
1695 GTEST_SKIP();
1696 }
Alec Mouric0aae732021-01-12 13:32:18 -08001697 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001698 fillBufferLayerTransform<ColorSourceVariant>();
1699}
1700
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001701TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001702 if (!GetParam()->typeSupported()) {
1703 GTEST_SKIP();
1704 }
Alec Mouric0aae732021-01-12 13:32:18 -08001705 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08001706 fillBufferColorTransform<ColorSourceVariant>();
1707}
1708
Sally Qi2019fd22021-11-22 10:19:04 -08001709TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_sourceDataspace) {
1710 const auto& renderEngineFactory = GetParam();
1711 // skip for non color management
Alec Mouri47bcb072023-08-15 02:02:49 +00001712 if (!renderEngineFactory->typeSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001713 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001714 }
1715
1716 initializeRenderEngine();
1717 fillBufferColorTransformAndSourceDataspace<ColorSourceVariant>();
1718}
1719
1720TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_outputDataspace) {
1721 const auto& renderEngineFactory = GetParam();
1722 // skip for non color management
Alec Mouri47bcb072023-08-15 02:02:49 +00001723 if (!renderEngineFactory->typeSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001724 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001725 }
1726
1727 initializeRenderEngine();
1728 fillBufferColorTransformAndOutputDataspace<ColorSourceVariant>();
1729}
1730
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001731TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001732 if (!GetParam()->typeSupported()) {
1733 GTEST_SKIP();
1734 }
Alec Mouric0aae732021-01-12 13:32:18 -08001735 initializeRenderEngine();
Alec Mouri7c94edb2018-12-03 21:23:26 -08001736 fillBufferWithRoundedCorners<ColorSourceVariant>();
1737}
1738
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001739TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001740 if (!GetParam()->typeSupported()) {
1741 GTEST_SKIP();
1742 }
Alec Mouric0aae732021-01-12 13:32:18 -08001743 initializeRenderEngine();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001744 fillBufferColorTransformZeroLayerAlpha<ColorSourceVariant>();
1745}
1746
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001747TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001748 if (!GetParam()->typeSupported()) {
1749 GTEST_SKIP();
1750 }
Alec Mouric0aae732021-01-12 13:32:18 -08001751 initializeRenderEngine();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001752 fillBufferAndBlurBackground<ColorSourceVariant>();
1753}
1754
Alec Mourie8489fd2021-04-29 16:08:56 -07001755TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001756 if (!GetParam()->typeSupported()) {
1757 GTEST_SKIP();
1758 }
Alec Mourie8489fd2021-04-29 16:08:56 -07001759 initializeRenderEngine();
1760 fillSmallLayerAndBlurBackground<ColorSourceVariant>();
1761}
1762
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001763TEST_P(RenderEngineTest, drawLayers_overlayCorners_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001764 if (!GetParam()->typeSupported()) {
1765 GTEST_SKIP();
1766 }
Alec Mouric0aae732021-01-12 13:32:18 -08001767 initializeRenderEngine();
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001768 overlayCorners<ColorSourceVariant>();
1769}
1770
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001771TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001772 if (!GetParam()->typeSupported()) {
1773 GTEST_SKIP();
1774 }
Alec Mouric0aae732021-01-12 13:32:18 -08001775 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001776 fillRedBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1777}
1778
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001779TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001780 if (!GetParam()->typeSupported()) {
1781 GTEST_SKIP();
1782 }
Alec Mouric0aae732021-01-12 13:32:18 -08001783 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001784 fillGreenBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1785}
1786
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001787TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001788 if (!GetParam()->typeSupported()) {
1789 GTEST_SKIP();
1790 }
Alec Mouric0aae732021-01-12 13:32:18 -08001791 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001792 fillBlueBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1793}
1794
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001795TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001796 if (!GetParam()->typeSupported()) {
1797 GTEST_SKIP();
1798 }
Alec Mouric0aae732021-01-12 13:32:18 -08001799 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001800 fillRedTransparentBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1801}
1802
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001803TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001804 if (!GetParam()->typeSupported()) {
1805 GTEST_SKIP();
1806 }
Alec Mouric0aae732021-01-12 13:32:18 -08001807 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001808 fillBufferPhysicalOffset<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1809}
1810
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001811TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001812 if (!GetParam()->typeSupported()) {
1813 GTEST_SKIP();
1814 }
Alec Mouric0aae732021-01-12 13:32:18 -08001815 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001816 fillBufferCheckersRotate0<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1817}
1818
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001819TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001820 if (!GetParam()->typeSupported()) {
1821 GTEST_SKIP();
1822 }
Alec Mouric0aae732021-01-12 13:32:18 -08001823 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001824 fillBufferCheckersRotate90<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1825}
1826
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001827TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001828 if (!GetParam()->typeSupported()) {
1829 GTEST_SKIP();
1830 }
Alec Mouric0aae732021-01-12 13:32:18 -08001831 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001832 fillBufferCheckersRotate180<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1833}
1834
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001835TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001836 if (!GetParam()->typeSupported()) {
1837 GTEST_SKIP();
1838 }
Alec Mouric0aae732021-01-12 13:32:18 -08001839 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001840 fillBufferCheckersRotate270<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1841}
1842
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001843TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001844 if (!GetParam()->typeSupported()) {
1845 GTEST_SKIP();
1846 }
Alec Mouric0aae732021-01-12 13:32:18 -08001847 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001848 fillBufferLayerTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1849}
1850
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001851TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001852 if (!GetParam()->typeSupported()) {
1853 GTEST_SKIP();
1854 }
Alec Mouric0aae732021-01-12 13:32:18 -08001855 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08001856 fillBufferColorTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1857}
1858
Sally Qi2019fd22021-11-22 10:19:04 -08001859TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndSourceDataspace_opaqueBufferSource) {
1860 const auto& renderEngineFactory = GetParam();
1861 // skip for non color management
Alec Mouri47bcb072023-08-15 02:02:49 +00001862 if (!renderEngineFactory->typeSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001863 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001864 }
1865
1866 initializeRenderEngine();
1867 fillBufferColorTransformAndSourceDataspace<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1868}
1869
1870TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndOutputDataspace_opaqueBufferSource) {
1871 const auto& renderEngineFactory = GetParam();
1872 // skip for non color management
Alec Mouri47bcb072023-08-15 02:02:49 +00001873 if (!renderEngineFactory->typeSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001874 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001875 }
1876
1877 initializeRenderEngine();
1878 fillBufferColorTransformAndOutputDataspace<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1879}
1880
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001881TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001882 if (!GetParam()->typeSupported()) {
1883 GTEST_SKIP();
1884 }
Alec Mouric0aae732021-01-12 13:32:18 -08001885 initializeRenderEngine();
Alec Mouri7c94edb2018-12-03 21:23:26 -08001886 fillBufferWithRoundedCorners<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1887}
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001888
Alec Mouric0aae732021-01-12 13:32:18 -08001889TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001890 if (!GetParam()->typeSupported()) {
1891 GTEST_SKIP();
1892 }
Alec Mouric0aae732021-01-12 13:32:18 -08001893 initializeRenderEngine();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001894 fillBufferColorTransformZeroLayerAlpha<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1895}
Alec Mouri7c94edb2018-12-03 21:23:26 -08001896
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001897TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001898 if (!GetParam()->typeSupported()) {
1899 GTEST_SKIP();
1900 }
Alec Mouric0aae732021-01-12 13:32:18 -08001901 initializeRenderEngine();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001902 fillBufferAndBlurBackground<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1903}
1904
Alec Mourie8489fd2021-04-29 16:08:56 -07001905TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001906 if (!GetParam()->typeSupported()) {
1907 GTEST_SKIP();
1908 }
Alec Mourie8489fd2021-04-29 16:08:56 -07001909 initializeRenderEngine();
1910 fillSmallLayerAndBlurBackground<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1911}
1912
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001913TEST_P(RenderEngineTest, drawLayers_overlayCorners_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001914 if (!GetParam()->typeSupported()) {
1915 GTEST_SKIP();
1916 }
Alec Mouric0aae732021-01-12 13:32:18 -08001917 initializeRenderEngine();
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001918 overlayCorners<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1919}
1920
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001921TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001922 if (!GetParam()->typeSupported()) {
1923 GTEST_SKIP();
1924 }
Alec Mouric0aae732021-01-12 13:32:18 -08001925 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001926 fillRedBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1927}
1928
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001929TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001930 if (!GetParam()->typeSupported()) {
1931 GTEST_SKIP();
1932 }
Alec Mouric0aae732021-01-12 13:32:18 -08001933 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001934 fillGreenBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1935}
1936
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001937TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001938 if (!GetParam()->typeSupported()) {
1939 GTEST_SKIP();
1940 }
Alec Mouric0aae732021-01-12 13:32:18 -08001941 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001942 fillBlueBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1943}
1944
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001945TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001946 if (!GetParam()->typeSupported()) {
1947 GTEST_SKIP();
1948 }
Alec Mouric0aae732021-01-12 13:32:18 -08001949 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001950 fillRedTransparentBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1951}
1952
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001953TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001954 if (!GetParam()->typeSupported()) {
1955 GTEST_SKIP();
1956 }
Alec Mouric0aae732021-01-12 13:32:18 -08001957 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001958 fillBufferPhysicalOffset<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1959}
1960
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001961TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001962 if (!GetParam()->typeSupported()) {
1963 GTEST_SKIP();
1964 }
Alec Mouric0aae732021-01-12 13:32:18 -08001965 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001966 fillBufferCheckersRotate0<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1967}
1968
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001969TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001970 if (!GetParam()->typeSupported()) {
1971 GTEST_SKIP();
1972 }
Alec Mouric0aae732021-01-12 13:32:18 -08001973 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001974 fillBufferCheckersRotate90<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1975}
1976
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001977TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001978 if (!GetParam()->typeSupported()) {
1979 GTEST_SKIP();
1980 }
Alec Mouric0aae732021-01-12 13:32:18 -08001981 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001982 fillBufferCheckersRotate180<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1983}
1984
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001985TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001986 if (!GetParam()->typeSupported()) {
1987 GTEST_SKIP();
1988 }
Alec Mouric0aae732021-01-12 13:32:18 -08001989 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001990 fillBufferCheckersRotate270<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1991}
1992
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001993TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001994 if (!GetParam()->typeSupported()) {
1995 GTEST_SKIP();
1996 }
Alec Mouric0aae732021-01-12 13:32:18 -08001997 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001998 fillBufferLayerTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1999}
2000
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002001TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002002 if (!GetParam()->typeSupported()) {
2003 GTEST_SKIP();
2004 }
Alec Mouric0aae732021-01-12 13:32:18 -08002005 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08002006 fillBufferColorTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2007}
2008
Sally Qi2019fd22021-11-22 10:19:04 -08002009TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndSourceDataspace_bufferSource) {
2010 const auto& renderEngineFactory = GetParam();
2011 // skip for non color management
Alec Mouri47bcb072023-08-15 02:02:49 +00002012 if (!renderEngineFactory->typeSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00002013 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08002014 }
2015
2016 initializeRenderEngine();
2017 fillBufferColorTransformAndSourceDataspace<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2018}
2019
2020TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndOutputDataspace_bufferSource) {
2021 const auto& renderEngineFactory = GetParam();
2022 // skip for non color management
Alec Mouri47bcb072023-08-15 02:02:49 +00002023 if (!renderEngineFactory->typeSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00002024 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08002025 }
2026
2027 initializeRenderEngine();
2028 fillBufferColorTransformAndOutputDataspace<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2029}
2030
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002031TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002032 if (!GetParam()->typeSupported()) {
2033 GTEST_SKIP();
2034 }
Alec Mouric0aae732021-01-12 13:32:18 -08002035 initializeRenderEngine();
Alec Mouri7c94edb2018-12-03 21:23:26 -08002036 fillBufferWithRoundedCorners<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2037}
2038
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08002039TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002040 if (!GetParam()->typeSupported()) {
2041 GTEST_SKIP();
2042 }
Alec Mouric0aae732021-01-12 13:32:18 -08002043 initializeRenderEngine();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08002044 fillBufferColorTransformZeroLayerAlpha<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2045}
2046
Nathaniel Nifong53494f32021-04-30 14:05:39 -04002047TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002048 if (!GetParam()->typeSupported()) {
2049 GTEST_SKIP();
2050 }
Alec Mouric0aae732021-01-12 13:32:18 -08002051 initializeRenderEngine();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08002052 fillBufferAndBlurBackground<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2053}
2054
Alec Mourie8489fd2021-04-29 16:08:56 -07002055TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002056 if (!GetParam()->typeSupported()) {
2057 GTEST_SKIP();
2058 }
Alec Mourie8489fd2021-04-29 16:08:56 -07002059 initializeRenderEngine();
2060 fillSmallLayerAndBlurBackground<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2061}
2062
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002063TEST_P(RenderEngineTest, drawLayers_overlayCorners_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002064 if (!GetParam()->typeSupported()) {
2065 GTEST_SKIP();
2066 }
Alec Mouric0aae732021-01-12 13:32:18 -08002067 initializeRenderEngine();
Alec Mourie7d1d4a2019-02-05 01:13:46 +00002068 overlayCorners<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2069}
2070
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002071TEST_P(RenderEngineTest, drawLayers_fillBufferTextureTransform) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002072 if (!GetParam()->typeSupported()) {
2073 GTEST_SKIP();
2074 }
Alec Mouric0aae732021-01-12 13:32:18 -08002075 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002076 fillBufferTextureTransform();
2077}
2078
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002079TEST_P(RenderEngineTest, drawLayers_fillBuffer_premultipliesAlpha) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002080 if (!GetParam()->typeSupported()) {
2081 GTEST_SKIP();
2082 }
Alec Mouric0aae732021-01-12 13:32:18 -08002083 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002084 fillBufferWithPremultiplyAlpha();
2085}
2086
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002087TEST_P(RenderEngineTest, drawLayers_fillBuffer_withoutPremultiplyingAlpha) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002088 if (!GetParam()->typeSupported()) {
2089 GTEST_SKIP();
2090 }
Alec Mouric0aae732021-01-12 13:32:18 -08002091 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002092 fillBufferWithoutPremultiplyAlpha();
2093}
2094
Alec Mouribd17b3b2020-12-17 11:08:30 -08002095TEST_P(RenderEngineTest, drawLayers_fillShadow_castsWithoutCasterLayer) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002096 if (!GetParam()->typeSupported()) {
2097 GTEST_SKIP();
2098 }
Alec Mouric0aae732021-01-12 13:32:18 -08002099 initializeRenderEngine();
Alec Mouribd17b3b2020-12-17 11:08:30 -08002100
Alec Mouri4049b532021-10-15 20:59:33 -07002101 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2102 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Alec Mouribd17b3b2020-12-17 11:08:30 -08002103 const float shadowLength = 5.0f;
2104 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2105 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2106 renderengine::ShadowSettings settings =
2107 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2108 false /* casterIsTranslucent */);
2109
2110 drawShadowWithoutCaster(casterBounds.toFloatRect(), settings, backgroundColor);
2111 expectShadowColorWithoutCaster(casterBounds.toFloatRect(), settings, backgroundColor);
2112}
2113
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002114TEST_P(RenderEngineTest, drawLayers_fillShadow_casterLayerMinSize) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002115 if (!GetParam()->typeSupported()) {
2116 GTEST_SKIP();
2117 }
Alec Mouric0aae732021-01-12 13:32:18 -08002118 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002119
Alec Mouri4049b532021-10-15 20:59:33 -07002120 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2121 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2122 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2123 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002124 const float shadowLength = 5.0f;
2125 Rect casterBounds(1, 1);
2126 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2127 renderengine::LayerSettings castingLayer;
2128 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2129 castingLayer.alpha = 1.0f;
2130 renderengine::ShadowSettings settings =
2131 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2132 false /* casterIsTranslucent */);
2133
2134 drawShadow<ColorSourceVariant>(castingLayer, settings, casterColor, backgroundColor);
2135 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2136}
2137
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002138TEST_P(RenderEngineTest, drawLayers_fillShadow_casterColorLayer) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002139 if (!GetParam()->typeSupported()) {
2140 GTEST_SKIP();
2141 }
Alec Mouric0aae732021-01-12 13:32:18 -08002142 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002143
Alec Mouri4049b532021-10-15 20:59:33 -07002144 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2145 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2146 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2147 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002148 const float shadowLength = 5.0f;
2149 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2150 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2151 renderengine::LayerSettings castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002152 castingLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002153 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2154 castingLayer.alpha = 1.0f;
2155 renderengine::ShadowSettings settings =
2156 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2157 false /* casterIsTranslucent */);
2158
2159 drawShadow<ColorSourceVariant>(castingLayer, settings, casterColor, backgroundColor);
2160 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2161}
2162
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002163TEST_P(RenderEngineTest, drawLayers_fillShadow_casterOpaqueBufferLayer) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002164 if (!GetParam()->typeSupported()) {
2165 GTEST_SKIP();
2166 }
Alec Mouric0aae732021-01-12 13:32:18 -08002167 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002168
Alec Mouri4049b532021-10-15 20:59:33 -07002169 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2170 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2171 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2172 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002173 const float shadowLength = 5.0f;
2174 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2175 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2176 renderengine::LayerSettings castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002177 castingLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002178 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2179 castingLayer.alpha = 1.0f;
2180 renderengine::ShadowSettings settings =
2181 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2182 false /* casterIsTranslucent */);
2183
2184 drawShadow<BufferSourceVariant<ForceOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2185 backgroundColor);
2186 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2187}
2188
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002189TEST_P(RenderEngineTest, drawLayers_fillShadow_casterWithRoundedCorner) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002190 if (!GetParam()->typeSupported()) {
2191 GTEST_SKIP();
2192 }
Alec Mouric0aae732021-01-12 13:32:18 -08002193 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002194
Alec Mouri4049b532021-10-15 20:59:33 -07002195 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2196 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2197 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2198 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002199 const float shadowLength = 5.0f;
2200 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2201 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2202 renderengine::LayerSettings castingLayer;
2203 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002204 castingLayer.geometry.roundedCornersRadius = {3.0f, 3.0f};
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002205 castingLayer.geometry.roundedCornersCrop = casterBounds.toFloatRect();
2206 castingLayer.alpha = 1.0f;
2207 renderengine::ShadowSettings settings =
2208 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2209 false /* casterIsTranslucent */);
2210
2211 drawShadow<BufferSourceVariant<ForceOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2212 backgroundColor);
2213 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2214}
2215
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002216TEST_P(RenderEngineTest, drawLayers_fillShadow_translucentCasterWithAlpha) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002217 if (!GetParam()->typeSupported()) {
2218 GTEST_SKIP();
2219 }
Alec Mouric0aae732021-01-12 13:32:18 -08002220 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002221
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002222 const ubyte4 casterColor(255, 0, 0, 255);
2223 const ubyte4 backgroundColor(255, 255, 255, 255);
2224 const float shadowLength = 5.0f;
2225 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2226 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2227 renderengine::LayerSettings castingLayer;
2228 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2229 castingLayer.alpha = 0.5f;
2230 renderengine::ShadowSettings settings =
2231 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2232 true /* casterIsTranslucent */);
2233
2234 drawShadow<BufferSourceVariant<RelaxOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2235 backgroundColor);
2236
2237 // verify only the background since the shadow will draw behind the caster
2238 const float shadowInset = settings.length * -1.0f;
2239 const Rect casterWithShadow =
2240 Rect(casterBounds).inset(shadowInset, shadowInset, shadowInset, shadowInset);
2241 const Region backgroundRegion = Region(fullscreenRect()).subtractSelf(casterWithShadow);
2242 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
2243 backgroundColor.a);
2244}
2245
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002246TEST_P(RenderEngineTest, cleanupPostRender_cleansUpOnce) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002247 if (!GetParam()->typeSupported()) {
2248 GTEST_SKIP();
2249 }
Alec Mouric0aae732021-01-12 13:32:18 -08002250 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002251
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002252 renderengine::DisplaySettings settings;
2253 settings.physicalDisplay = fullscreenRect();
2254 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002255 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002256
Sally Qi59a9f502021-10-12 18:53:23 +00002257 std::vector<renderengine::LayerSettings> layers;
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002258 renderengine::LayerSettings layer;
2259 layer.geometry.boundaries = fullscreenRect().toFloatRect();
2260 BufferSourceVariant<ForceOpaqueBufferVariant>::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
2261 layer.alpha = 1.0;
Sally Qi59a9f502021-10-12 18:53:23 +00002262 layers.push_back(layer);
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002263
Patrick Williams2e9748f2022-08-09 22:48:18 +00002264 ftl::Future<FenceResult> futureOne =
Alec Mourif29700f2023-08-17 21:53:31 +00002265 mRE->drawLayers(settings, layers, mBuffer, base::unique_fd());
Patrick Williams2e9748f2022-08-09 22:48:18 +00002266 ASSERT_TRUE(futureOne.valid());
2267 auto resultOne = futureOne.get();
2268 ASSERT_TRUE(resultOne.ok());
2269 auto fenceOne = resultOne.value();
Sally Qi4cabdd02021-08-05 16:45:57 -07002270
Patrick Williams2e9748f2022-08-09 22:48:18 +00002271 ftl::Future<FenceResult> futureTwo =
Alec Mourif29700f2023-08-17 21:53:31 +00002272 mRE->drawLayers(settings, layers, mBuffer, base::unique_fd(fenceOne->dup()));
Patrick Williams2e9748f2022-08-09 22:48:18 +00002273 ASSERT_TRUE(futureTwo.valid());
2274 auto resultTwo = futureTwo.get();
2275 ASSERT_TRUE(resultTwo.ok());
2276 auto fenceTwo = resultTwo.value();
2277 fenceTwo->waitForever(LOG_TAG);
Derek Sollenbergerec411212021-08-25 10:54:47 -04002278
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002279 // Only cleanup the first time.
Ian Elliott1f0911e2022-09-09 16:31:47 -06002280 if (mRE->canSkipPostRenderCleanup()) {
2281 // Skia's Vk backend may keep the texture alive beyond drawLayersInternal, so
2282 // it never gets added to the cleanup list. In those cases, we can skip.
2283 EXPECT_TRUE(GetParam()->type() == renderengine::RenderEngine::RenderEngineType::SKIA_VK);
2284 } else {
2285 mRE->cleanupPostRender();
2286 EXPECT_TRUE(mRE->canSkipPostRenderCleanup());
2287 }
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002288}
2289
Ana Krulecf9a15d92020-12-11 08:35:00 -08002290TEST_P(RenderEngineTest, testRoundedCornersCrop) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002291 if (!GetParam()->typeSupported()) {
2292 GTEST_SKIP();
2293 }
Alec Mouric0aae732021-01-12 13:32:18 -08002294 initializeRenderEngine();
Ana Krulecf9a15d92020-12-11 08:35:00 -08002295
2296 renderengine::DisplaySettings settings;
2297 settings.physicalDisplay = fullscreenRect();
2298 settings.clip = fullscreenRect();
2299 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2300
Sally Qi59a9f502021-10-12 18:53:23 +00002301 std::vector<renderengine::LayerSettings> layers;
Ana Krulecf9a15d92020-12-11 08:35:00 -08002302
2303 renderengine::LayerSettings redLayer;
2304 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2305 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002306 redLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
2307
Ana Krulecf9a15d92020-12-11 08:35:00 -08002308 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2309 // Red background.
2310 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2311 redLayer.alpha = 1.0f;
2312
Sally Qi59a9f502021-10-12 18:53:23 +00002313 layers.push_back(redLayer);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002314
2315 // Green layer with 1/3 size.
2316 renderengine::LayerSettings greenLayer;
2317 greenLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2318 greenLayer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002319 greenLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
Ana Krulecf9a15d92020-12-11 08:35:00 -08002320 // Bottom right corner is not going to be rounded.
2321 greenLayer.geometry.roundedCornersCrop =
2322 Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3, DEFAULT_DISPLAY_HEIGHT,
2323 DEFAULT_DISPLAY_HEIGHT)
2324 .toFloatRect();
2325 greenLayer.source.solidColor = half3(0.0f, 1.0f, 0.0f);
2326 greenLayer.alpha = 1.0f;
2327
Sally Qi59a9f502021-10-12 18:53:23 +00002328 layers.push_back(greenLayer);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002329
Alec Mouric0aae732021-01-12 13:32:18 -08002330 invokeDraw(settings, layers);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002331
2332 // Corners should be ignored...
2333 // Screen size: width is 128, height is 256.
2334 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 0);
2335 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, 0, DEFAULT_DISPLAY_WIDTH, 1), 0, 0, 0, 0);
2336 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT - 1, 1, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
2337 // Bottom right corner is kept out of the clipping, and it's green.
2338 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1,
2339 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
2340 0, 255, 0, 255);
2341}
2342
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002343TEST_P(RenderEngineTest, testRoundedCornersParentCrop) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002344 if (!GetParam()->typeSupported()) {
2345 GTEST_SKIP();
2346 }
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002347 initializeRenderEngine();
2348
2349 renderengine::DisplaySettings settings;
2350 settings.physicalDisplay = fullscreenRect();
2351 settings.clip = fullscreenRect();
2352 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2353
Sally Qi59a9f502021-10-12 18:53:23 +00002354 std::vector<renderengine::LayerSettings> layers;
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002355
2356 renderengine::LayerSettings redLayer;
2357 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2358 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002359 redLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002360 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2361 // Red background.
2362 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2363 redLayer.alpha = 1.0f;
2364
Sally Qi59a9f502021-10-12 18:53:23 +00002365 layers.push_back(redLayer);
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002366
2367 // Green layer with 1/2 size with parent crop rect.
2368 renderengine::LayerSettings greenLayer = redLayer;
2369 greenLayer.geometry.boundaries =
2370 FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT / 2);
2371 greenLayer.source.solidColor = half3(0.0f, 1.0f, 0.0f);
2372
Sally Qi59a9f502021-10-12 18:53:23 +00002373 layers.push_back(greenLayer);
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002374
2375 invokeDraw(settings, layers);
2376
2377 // Due to roundedCornersRadius, the corners are untouched.
2378 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2379 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2380 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2381 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2382
2383 // top middle should be green and the bottom middle red
2384 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, 0), 0, 255, 0, 255);
2385 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0, 255);
2386
2387 // the bottom edge of the green layer should not be rounded
2388 expectBufferColor(Point(0, (DEFAULT_DISPLAY_HEIGHT / 2) - 1), 0, 255, 0, 255);
2389}
2390
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002391TEST_P(RenderEngineTest, testRoundedCornersParentCropSmallBounds) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002392 if (!GetParam()->typeSupported()) {
2393 GTEST_SKIP();
2394 }
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002395 initializeRenderEngine();
2396
2397 renderengine::DisplaySettings settings;
2398 settings.physicalDisplay = fullscreenRect();
2399 settings.clip = fullscreenRect();
2400 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2401
Sally Qi59a9f502021-10-12 18:53:23 +00002402 std::vector<renderengine::LayerSettings> layers;
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002403
2404 renderengine::LayerSettings redLayer;
2405 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2406 redLayer.geometry.boundaries = FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, 32);
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002407 redLayer.geometry.roundedCornersRadius = {64.0f, 64.0f};
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002408 redLayer.geometry.roundedCornersCrop = FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, 128);
2409 // Red background.
2410 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2411 redLayer.alpha = 1.0f;
2412
Sally Qi59a9f502021-10-12 18:53:23 +00002413 layers.push_back(redLayer);
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002414 invokeDraw(settings, layers);
2415
2416 // Due to roundedCornersRadius, the top corners are untouched.
2417 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2418 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2419
2420 // ensure that the entire height of the red layer was clipped by the rounded corners crop.
2421 expectBufferColor(Point(0, 31), 0, 0, 0, 0);
2422 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 31), 0, 0, 0, 0);
2423
2424 // the bottom middle should be red
2425 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, 31), 255, 0, 0, 255);
2426}
2427
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002428TEST_P(RenderEngineTest, testRoundedCornersXY) {
2429 if (GetParam()->type() != renderengine::RenderEngine::RenderEngineType::SKIA_GL) {
2430 GTEST_SKIP();
2431 }
2432
2433 initializeRenderEngine();
2434
2435 renderengine::DisplaySettings settings;
2436 settings.physicalDisplay = fullscreenRect();
2437 settings.clip = fullscreenRect();
2438 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2439
2440 std::vector<renderengine::LayerSettings> layers;
2441
2442 renderengine::LayerSettings redLayer;
2443 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2444 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
2445 redLayer.geometry.roundedCornersRadius = {5.0f, 20.0f};
2446 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2447 // Red background.
2448 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2449 redLayer.alpha = 1.0f;
2450
2451 layers.push_back(redLayer);
2452
2453 invokeDraw(settings, layers);
2454
2455 // Due to roundedCornersRadius, the corners are untouched.
2456 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2457 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2458 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2459 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2460
2461 // Y-axis draws a larger radius, check that its untouched as well
2462 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 5), 0, 0, 0, 0);
2463 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 5), 0, 0, 0, 0);
2464 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 5), 0, 0, 0, 0);
2465 expectBufferColor(Point(0, 5), 0, 0, 0, 0);
2466
2467 // middle should be red
2468 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0, 255);
2469}
2470
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002471TEST_P(RenderEngineTest, testClear) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002472 if (!GetParam()->typeSupported()) {
2473 GTEST_SKIP();
2474 }
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002475 initializeRenderEngine();
2476
2477 const auto rect = fullscreenRect();
2478 const renderengine::DisplaySettings display{
2479 .physicalDisplay = rect,
2480 .clip = rect,
2481 };
2482
2483 const renderengine::LayerSettings redLayer{
2484 .geometry.boundaries = rect.toFloatRect(),
2485 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
2486 .alpha = 1.0f,
2487 };
2488
2489 // This mimics prepareClearClientComposition. This layer should overwrite
2490 // the redLayer, so that the buffer is transparent, rather than red.
2491 const renderengine::LayerSettings clearLayer{
2492 .geometry.boundaries = rect.toFloatRect(),
2493 .source.solidColor = half3(0.0f, 0.0f, 0.0f),
2494 .alpha = 0.0f,
2495 .disableBlending = true,
2496 };
2497
Sally Qi59a9f502021-10-12 18:53:23 +00002498 std::vector<renderengine::LayerSettings> layers{redLayer, clearLayer};
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002499 invokeDraw(display, layers);
2500 expectBufferColor(rect, 0, 0, 0, 0);
2501}
2502
2503TEST_P(RenderEngineTest, testDisableBlendingBuffer) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002504 if (!GetParam()->typeSupported()) {
2505 GTEST_SKIP();
2506 }
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002507 initializeRenderEngine();
2508
2509 const auto rect = Rect(0, 0, 1, 1);
2510 const renderengine::DisplaySettings display{
2511 .physicalDisplay = rect,
2512 .clip = rect,
2513 };
2514
2515 const renderengine::LayerSettings redLayer{
2516 .geometry.boundaries = rect.toFloatRect(),
2517 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
2518 .alpha = 1.0f,
2519 };
2520
2521 // The next layer will overwrite redLayer with a GraphicBuffer that is green
2522 // applied with a translucent alpha.
Alec Mouria90a5702021-04-16 16:36:21 +00002523 const auto buf = allocateSourceBuffer(1, 1);
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002524 {
2525 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00002526 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2527 reinterpret_cast<void**>(&pixels));
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002528 pixels[0] = 0;
2529 pixels[1] = 255;
2530 pixels[2] = 0;
2531 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00002532 buf->getBuffer()->unlock();
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002533 }
2534
2535 const renderengine::LayerSettings greenLayer{
2536 .geometry.boundaries = rect.toFloatRect(),
2537 .source =
2538 renderengine::PixelSource{
2539 .buffer =
2540 renderengine::Buffer{
2541 .buffer = buf,
2542 .usePremultipliedAlpha = true,
2543 },
2544 },
2545 .alpha = 0.5f,
2546 .disableBlending = true,
2547 };
2548
Sally Qi59a9f502021-10-12 18:53:23 +00002549 std::vector<renderengine::LayerSettings> layers{redLayer, greenLayer};
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002550 invokeDraw(display, layers);
2551 expectBufferColor(rect, 0, 128, 0, 128);
2552}
2553
Tianhao Yao67dd7122022-02-22 17:48:33 +00002554TEST_P(RenderEngineTest, testBorder) {
2555 if (GetParam()->type() != renderengine::RenderEngine::RenderEngineType::SKIA_GL) {
2556 GTEST_SKIP();
2557 }
2558
Tianhao Yao67dd7122022-02-22 17:48:33 +00002559 initializeRenderEngine();
2560
2561 const ui::Dataspace dataspace = ui::Dataspace::V0_SRGB;
2562
2563 const auto displayRect = Rect(1080, 2280);
2564 renderengine::DisplaySettings display{
2565 .physicalDisplay = displayRect,
2566 .clip = displayRect,
2567 .outputDataspace = dataspace,
2568 };
2569 display.borderInfoList.clear();
2570 renderengine::BorderRenderInfo info;
2571 info.combinedRegion = Region(Rect(99, 99, 199, 199));
Tianhao Yao10cea3c2022-03-30 01:37:22 +00002572 info.width = 20.0f;
2573 info.color = half4{1.0f, 128.0f / 255.0f, 0.0f, 1.0f};
Tianhao Yao67dd7122022-02-22 17:48:33 +00002574 display.borderInfoList.emplace_back(info);
2575
2576 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2577 const renderengine::LayerSettings greenLayer{
2578 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2579 .source =
2580 renderengine::PixelSource{
2581 .buffer =
2582 renderengine::Buffer{
2583 .buffer = greenBuffer,
2584 .usePremultipliedAlpha = true,
2585 },
2586 },
2587 .alpha = 1.0f,
2588 .sourceDataspace = dataspace,
2589 .whitePointNits = 200.f,
2590 };
2591
2592 std::vector<renderengine::LayerSettings> layers;
2593 layers.emplace_back(greenLayer);
2594 invokeDraw(display, layers);
2595
2596 expectBufferColor(Rect(99, 99, 101, 101), 255, 128, 0, 255, 1);
2597}
2598
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002599TEST_P(RenderEngineTest, testDimming) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002600 if (!GetParam()->typeSupported()) {
2601 GTEST_SKIP();
2602 }
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002603 initializeRenderEngine();
2604
Alec Mouri85065692022-03-18 00:58:26 +00002605 const ui::Dataspace dataspace = ui::Dataspace::V0_SRGB_LINEAR;
2606
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002607 const auto displayRect = Rect(3, 1);
2608 const renderengine::DisplaySettings display{
2609 .physicalDisplay = displayRect,
2610 .clip = displayRect,
Alec Mouri85065692022-03-18 00:58:26 +00002611 .outputDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002612 .targetLuminanceNits = 1000.f,
2613 };
2614
2615 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2616 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2617 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2618
2619 const renderengine::LayerSettings greenLayer{
2620 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2621 .source =
2622 renderengine::PixelSource{
2623 .buffer =
2624 renderengine::Buffer{
2625 .buffer = greenBuffer,
2626 .usePremultipliedAlpha = true,
2627 },
2628 },
2629 .alpha = 1.0f,
Alec Mouri85065692022-03-18 00:58:26 +00002630 .sourceDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002631 .whitePointNits = 200.f,
2632 };
2633
2634 const renderengine::LayerSettings blueLayer{
2635 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2636 .source =
2637 renderengine::PixelSource{
2638 .buffer =
2639 renderengine::Buffer{
2640 .buffer = blueBuffer,
2641 .usePremultipliedAlpha = true,
2642 },
2643 },
2644 .alpha = 1.0f,
Alec Mouri85065692022-03-18 00:58:26 +00002645 .sourceDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002646 .whitePointNits = 1000.f / 51.f,
2647 };
2648
2649 const renderengine::LayerSettings redLayer{
2650 .geometry.boundaries = FloatRect(2.f, 0.f, 3.f, 1.f),
2651 .source =
2652 renderengine::PixelSource{
2653 .buffer =
2654 renderengine::Buffer{
2655 .buffer = redBuffer,
2656 .usePremultipliedAlpha = true,
2657 },
2658 },
2659 .alpha = 1.0f,
Alec Mouri85065692022-03-18 00:58:26 +00002660 .sourceDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002661 // When the white point is not set for a layer, just ignore it and treat it as the same
2662 // as the max layer
2663 .whitePointNits = -1.f,
2664 };
2665
2666 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer, redLayer};
2667 invokeDraw(display, layers);
2668
2669 expectBufferColor(Rect(1, 1), 0, 51, 0, 255, 1);
2670 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 5, 255, 1);
2671 expectBufferColor(Rect(2, 0, 3, 1), 51, 0, 0, 255, 1);
2672}
2673
Alec Mouri85065692022-03-18 00:58:26 +00002674TEST_P(RenderEngineTest, testDimming_inGammaSpace) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002675 if (!GetParam()->typeSupported()) {
2676 GTEST_SKIP();
2677 }
Alec Mouri85065692022-03-18 00:58:26 +00002678 initializeRenderEngine();
2679
2680 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2681 ui::Dataspace::TRANSFER_GAMMA2_2 |
2682 ui::Dataspace::RANGE_FULL);
2683
2684 const auto displayRect = Rect(3, 1);
2685 const renderengine::DisplaySettings display{
2686 .physicalDisplay = displayRect,
2687 .clip = displayRect,
2688 .outputDataspace = dataspace,
2689 .targetLuminanceNits = 1000.f,
2690 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2691 };
2692
2693 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2694 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2695 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2696
2697 const renderengine::LayerSettings greenLayer{
2698 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2699 .source =
2700 renderengine::PixelSource{
2701 .buffer =
2702 renderengine::Buffer{
2703 .buffer = greenBuffer,
2704 .usePremultipliedAlpha = true,
2705 },
2706 },
2707 .alpha = 1.0f,
2708 .sourceDataspace = dataspace,
2709 .whitePointNits = 200.f,
2710 };
2711
2712 const renderengine::LayerSettings blueLayer{
2713 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2714 .source =
2715 renderengine::PixelSource{
2716 .buffer =
2717 renderengine::Buffer{
2718 .buffer = blueBuffer,
2719 .usePremultipliedAlpha = true,
2720 },
2721 },
2722 .alpha = 1.0f,
2723 .sourceDataspace = dataspace,
2724 .whitePointNits = 1000.f / 51.f,
2725 };
2726
2727 const renderengine::LayerSettings redLayer{
2728 .geometry.boundaries = FloatRect(2.f, 0.f, 3.f, 1.f),
2729 .source =
2730 renderengine::PixelSource{
2731 .buffer =
2732 renderengine::Buffer{
2733 .buffer = redBuffer,
2734 .usePremultipliedAlpha = true,
2735 },
2736 },
2737 .alpha = 1.0f,
2738 .sourceDataspace = dataspace,
2739 // When the white point is not set for a layer, just ignore it and treat it as the same
2740 // as the max layer
2741 .whitePointNits = -1.f,
2742 };
2743
2744 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer, redLayer};
2745 invokeDraw(display, layers);
2746
2747 expectBufferColor(Rect(1, 1), 0, 122, 0, 255, 1);
2748 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 42, 255, 1);
2749 expectBufferColor(Rect(2, 0, 3, 1), 122, 0, 0, 255, 1);
2750}
2751
Alec Mouri9bcd1d12022-04-21 22:16:56 +00002752TEST_P(RenderEngineTest, testDimming_inGammaSpace_withDisplayColorTransform) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002753 if (!GetParam()->typeSupported()) {
2754 GTEST_SKIP();
2755 }
Alec Mouri9bcd1d12022-04-21 22:16:56 +00002756 initializeRenderEngine();
2757
2758 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2759 ui::Dataspace::TRANSFER_GAMMA2_2 |
2760 ui::Dataspace::RANGE_FULL);
2761
2762 const auto displayRect = Rect(3, 1);
2763 const renderengine::DisplaySettings display{
2764 .physicalDisplay = displayRect,
2765 .clip = displayRect,
2766 .outputDataspace = dataspace,
2767 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
2768 .targetLuminanceNits = 1000.f,
2769 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2770 };
2771
2772 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2773 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2774 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2775
2776 const renderengine::LayerSettings greenLayer{
2777 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2778 .source =
2779 renderengine::PixelSource{
2780 .buffer =
2781 renderengine::Buffer{
2782 .buffer = greenBuffer,
2783 .usePremultipliedAlpha = true,
2784 },
2785 },
2786 .alpha = 1.0f,
2787 .sourceDataspace = dataspace,
2788 .whitePointNits = 200.f,
2789 };
2790
2791 const renderengine::LayerSettings redLayer{
2792 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2793 .source =
2794 renderengine::PixelSource{
2795 .buffer =
2796 renderengine::Buffer{
2797 .buffer = redBuffer,
2798 .usePremultipliedAlpha = true,
2799 },
2800 },
2801 .alpha = 1.0f,
2802 .sourceDataspace = dataspace,
2803 // When the white point is not set for a layer, just ignore it and treat it as the same
2804 // as the max layer
2805 .whitePointNits = -1.f,
2806 };
2807
2808 std::vector<renderengine::LayerSettings> layers{greenLayer, redLayer};
2809 invokeDraw(display, layers);
2810
2811 expectBufferColor(Rect(1, 1), 0, 0, 0, 255, 1);
2812 expectBufferColor(Rect(1, 0, 2, 1), 0, 122, 0, 255, 1);
2813}
2814
2815TEST_P(RenderEngineTest, testDimming_inGammaSpace_withDisplayColorTransform_deviceHandles) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002816 if (!GetParam()->typeSupported()) {
2817 GTEST_SKIP();
2818 }
Alec Mouri9bcd1d12022-04-21 22:16:56 +00002819 initializeRenderEngine();
2820
2821 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2822 ui::Dataspace::TRANSFER_GAMMA2_2 |
2823 ui::Dataspace::RANGE_FULL);
2824
2825 const auto displayRect = Rect(3, 1);
2826 const renderengine::DisplaySettings display{
2827 .physicalDisplay = displayRect,
2828 .clip = displayRect,
2829 .outputDataspace = dataspace,
2830 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
2831 .deviceHandlesColorTransform = true,
2832 .targetLuminanceNits = 1000.f,
2833 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2834 };
2835
2836 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2837 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2838 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2839
2840 const renderengine::LayerSettings greenLayer{
2841 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2842 .source =
2843 renderengine::PixelSource{
2844 .buffer =
2845 renderengine::Buffer{
2846 .buffer = greenBuffer,
2847 .usePremultipliedAlpha = true,
2848 },
2849 },
2850 .alpha = 1.0f,
2851 .sourceDataspace = dataspace,
2852 .whitePointNits = 200.f,
2853 };
2854
2855 const renderengine::LayerSettings redLayer{
2856 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2857 .source =
2858 renderengine::PixelSource{
2859 .buffer =
2860 renderengine::Buffer{
2861 .buffer = redBuffer,
2862 .usePremultipliedAlpha = true,
2863 },
2864 },
2865 .alpha = 1.0f,
2866 .sourceDataspace = dataspace,
2867 // When the white point is not set for a layer, just ignore it and treat it as the same
2868 // as the max layer
2869 .whitePointNits = -1.f,
2870 };
2871
2872 std::vector<renderengine::LayerSettings> layers{greenLayer, redLayer};
2873 invokeDraw(display, layers);
2874
2875 expectBufferColor(Rect(1, 1), 0, 122, 0, 255, 1);
2876 expectBufferColor(Rect(1, 0, 2, 1), 122, 0, 0, 255, 1);
2877}
2878
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002879TEST_P(RenderEngineTest, testDimming_withoutTargetLuminance) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002880 if (!GetParam()->typeSupported()) {
2881 GTEST_SKIP();
2882 }
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002883 initializeRenderEngine();
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002884
2885 const auto displayRect = Rect(2, 1);
2886 const renderengine::DisplaySettings display{
2887 .physicalDisplay = displayRect,
2888 .clip = displayRect,
2889 .outputDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2890 .targetLuminanceNits = -1.f,
2891 };
2892
2893 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2894 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2895
2896 const renderengine::LayerSettings greenLayer{
2897 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2898 .source =
2899 renderengine::PixelSource{
2900 .buffer =
2901 renderengine::Buffer{
2902 .buffer = greenBuffer,
2903 .usePremultipliedAlpha = true,
2904 },
2905 },
2906 .alpha = 1.0f,
2907 .sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2908 .whitePointNits = 200.f,
2909 };
2910
2911 const renderengine::LayerSettings blueLayer{
2912 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2913 .source =
2914 renderengine::PixelSource{
2915 .buffer =
2916 renderengine::Buffer{
2917 .buffer = blueBuffer,
2918 .usePremultipliedAlpha = true,
2919 },
2920 },
2921 .alpha = 1.0f,
2922 .sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2923 .whitePointNits = 1000.f,
2924 };
2925
2926 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer};
2927 invokeDraw(display, layers);
2928
2929 expectBufferColor(Rect(1, 1), 0, 51, 0, 255, 1);
2930 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 255, 255);
2931}
2932
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002933TEST_P(RenderEngineTest, test_isOpaque) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002934 if (!GetParam()->typeSupported()) {
2935 GTEST_SKIP();
2936 }
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002937 initializeRenderEngine();
2938
2939 const auto rect = Rect(0, 0, 1, 1);
2940 const renderengine::DisplaySettings display{
2941 .physicalDisplay = rect,
2942 .clip = rect,
2943 .outputDataspace = ui::Dataspace::DISPLAY_P3,
2944 };
2945
2946 // Create an unpremul buffer that is green with no alpha. Using isOpaque
2947 // should make the green show.
2948 const auto buf = allocateSourceBuffer(1, 1);
2949 {
2950 uint8_t* pixels;
2951 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2952 reinterpret_cast<void**>(&pixels));
2953 pixels[0] = 0;
2954 pixels[1] = 255;
2955 pixels[2] = 0;
2956 pixels[3] = 0;
2957 buf->getBuffer()->unlock();
2958 }
2959
2960 const renderengine::LayerSettings greenLayer{
2961 .geometry.boundaries = rect.toFloatRect(),
2962 .source =
2963 renderengine::PixelSource{
2964 .buffer =
2965 renderengine::Buffer{
2966 .buffer = buf,
2967 // Although the pixels are not
2968 // premultiplied in practice, this
2969 // matches the input we see.
2970 .usePremultipliedAlpha = true,
2971 .isOpaque = true,
2972 },
2973 },
2974 .alpha = 1.0f,
2975 };
2976
Sally Qi59a9f502021-10-12 18:53:23 +00002977 std::vector<renderengine::LayerSettings> layers{greenLayer};
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002978 invokeDraw(display, layers);
2979
Alec Mouri47bcb072023-08-15 02:02:49 +00002980 expectBufferColor(rect, 117, 251, 76, 255);
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002981}
Alec Mouri4049b532021-10-15 20:59:33 -07002982
Alec Mouri4049b532021-10-15 20:59:33 -07002983TEST_P(RenderEngineTest, test_tonemapPQMatches) {
Alec Mouri47bcb072023-08-15 02:02:49 +00002984 if (!GetParam()->typeSupported()) {
Alec Mouri5a493722022-01-26 16:43:02 -08002985 GTEST_SKIP();
Alec Mouri4049b532021-10-15 20:59:33 -07002986 }
2987
Alec Mouri4049b532021-10-15 20:59:33 -07002988 initializeRenderEngine();
2989
Alec Mouri5a493722022-01-26 16:43:02 -08002990 tonemap(
2991 static_cast<ui::Dataspace>(HAL_DATASPACE_STANDARD_BT2020 |
2992 HAL_DATASPACE_TRANSFER_ST2084 | HAL_DATASPACE_RANGE_FULL),
2993 [](vec3 color) { return EOTF_PQ(color); },
2994 [](vec3 color, float) {
2995 static constexpr float kMaxPQLuminance = 10000.f;
2996 return color * kMaxPQLuminance;
2997 });
2998}
Alec Mouri4049b532021-10-15 20:59:33 -07002999
Alec Mouri5a493722022-01-26 16:43:02 -08003000TEST_P(RenderEngineTest, test_tonemapHLGMatches) {
Alec Mouri47bcb072023-08-15 02:02:49 +00003001 if (!GetParam()->typeSupported()) {
Alec Mouri5a493722022-01-26 16:43:02 -08003002 GTEST_SKIP();
Alec Mouri4049b532021-10-15 20:59:33 -07003003 }
3004
Alec Mouri5a493722022-01-26 16:43:02 -08003005 initializeRenderEngine();
Alec Mouri4049b532021-10-15 20:59:33 -07003006
Alec Mouri5a493722022-01-26 16:43:02 -08003007 tonemap(
3008 static_cast<ui::Dataspace>(HAL_DATASPACE_STANDARD_BT2020 | HAL_DATASPACE_TRANSFER_HLG |
3009 HAL_DATASPACE_RANGE_FULL),
3010 [](vec3 color) { return EOTF_HLG(color); },
3011 [](vec3 color, float currentLuminaceNits) {
3012 static constexpr float kMaxHLGLuminance = 1000.f;
Alec Mouri7a577452022-03-04 23:41:38 +00003013 return color * kMaxHLGLuminance;
Alec Mouri5a493722022-01-26 16:43:02 -08003014 });
Alec Mouri4049b532021-10-15 20:59:33 -07003015}
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -05003016
3017TEST_P(RenderEngineTest, r8_behaves_as_mask) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003018 if (!GetParam()->typeSupported()) {
3019 GTEST_SKIP();
3020 }
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -05003021 initializeRenderEngine();
3022
3023 const auto r8Buffer = allocateR8Buffer(2, 1);
3024 if (!r8Buffer) {
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003025 GTEST_SKIP() << "Test is only necessary on devices that support r8";
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -05003026 return;
3027 }
3028 {
3029 uint8_t* pixels;
3030 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
3031 reinterpret_cast<void**>(&pixels));
3032 // This will be drawn on top of a green buffer. We'll verify that 255
3033 // results in keeping the original green and 0 results in black.
3034 pixels[0] = 0;
3035 pixels[1] = 255;
3036 r8Buffer->getBuffer()->unlock();
3037 }
3038
3039 const auto rect = Rect(0, 0, 2, 1);
3040 const renderengine::DisplaySettings display{
3041 .physicalDisplay = rect,
3042 .clip = rect,
3043 .outputDataspace = ui::Dataspace::SRGB,
3044 };
3045
3046 const auto greenBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(0, 255, 0, 255));
3047 const renderengine::LayerSettings greenLayer{
3048 .geometry.boundaries = rect.toFloatRect(),
3049 .source =
3050 renderengine::PixelSource{
3051 .buffer =
3052 renderengine::Buffer{
3053 .buffer = greenBuffer,
3054 },
3055 },
3056 .alpha = 1.0f,
3057 };
3058 const renderengine::LayerSettings r8Layer{
3059 .geometry.boundaries = rect.toFloatRect(),
3060 .source =
3061 renderengine::PixelSource{
3062 .buffer =
3063 renderengine::Buffer{
3064 .buffer = r8Buffer,
3065 },
3066 },
3067 .alpha = 1.0f,
3068 };
3069
3070 std::vector<renderengine::LayerSettings> layers{greenLayer, r8Layer};
3071 invokeDraw(display, layers);
3072
3073 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 255);
3074 expectBufferColor(Rect(1, 0, 2, 1), 0, 255, 0, 255);
3075}
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003076
3077TEST_P(RenderEngineTest, r8_respects_color_transform) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003078 if (!GetParam()->typeSupported()) {
3079 GTEST_SKIP();
3080 }
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003081 initializeRenderEngine();
3082
3083 const auto r8Buffer = allocateR8Buffer(2, 1);
3084 if (!r8Buffer) {
3085 GTEST_SKIP() << "Test is only necessary on devices that support r8";
3086 return;
3087 }
3088 {
3089 uint8_t* pixels;
3090 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
3091 reinterpret_cast<void**>(&pixels));
3092 pixels[0] = 0;
3093 pixels[1] = 255;
3094 r8Buffer->getBuffer()->unlock();
3095 }
3096
3097 const auto rect = Rect(0, 0, 2, 1);
3098 const renderengine::DisplaySettings display{
3099 .physicalDisplay = rect,
3100 .clip = rect,
3101 .outputDataspace = ui::Dataspace::SRGB,
3102 // Verify that the R8 layer respects the color transform when
3103 // deviceHandlesColorTransform is false. This transform converts
3104 // pure red to pure green. That will occur when the R8 buffer is
3105 // 255. When the R8 buffer is 0, it will still change to black, as
3106 // with r8_behaves_as_mask.
Alec Mouri9bcd1d12022-04-21 22:16:56 +00003107 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003108 .deviceHandlesColorTransform = false,
3109 };
3110
3111 const auto redBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(255, 0, 0, 255));
3112 const renderengine::LayerSettings redLayer{
3113 .geometry.boundaries = rect.toFloatRect(),
3114 .source =
3115 renderengine::PixelSource{
3116 .buffer =
3117 renderengine::Buffer{
3118 .buffer = redBuffer,
3119 },
3120 },
3121 .alpha = 1.0f,
3122 };
3123 const renderengine::LayerSettings r8Layer{
3124 .geometry.boundaries = rect.toFloatRect(),
3125 .source =
3126 renderengine::PixelSource{
3127 .buffer =
3128 renderengine::Buffer{
3129 .buffer = r8Buffer,
3130 },
3131 },
3132 .alpha = 1.0f,
3133 };
3134
3135 std::vector<renderengine::LayerSettings> layers{redLayer, r8Layer};
3136 invokeDraw(display, layers);
3137
3138 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 255);
3139 expectBufferColor(Rect(1, 0, 2, 1), 0, 255, 0, 255);
3140}
3141
3142TEST_P(RenderEngineTest, r8_respects_color_transform_when_device_handles) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003143 if (!GetParam()->typeSupported()) {
3144 GTEST_SKIP();
3145 }
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003146 initializeRenderEngine();
3147
3148 const auto r8Buffer = allocateR8Buffer(2, 1);
3149 if (!r8Buffer) {
3150 GTEST_SKIP() << "Test is only necessary on devices that support r8";
3151 return;
3152 }
3153 {
3154 uint8_t* pixels;
3155 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
3156 reinterpret_cast<void**>(&pixels));
3157 pixels[0] = 0;
3158 pixels[1] = 255;
3159 r8Buffer->getBuffer()->unlock();
3160 }
3161
3162 const auto rect = Rect(0, 0, 2, 1);
3163 const renderengine::DisplaySettings display{
3164 .physicalDisplay = rect,
3165 .clip = rect,
3166 .outputDataspace = ui::Dataspace::SRGB,
3167 // If deviceHandlesColorTransform is true, pixels where the A8
3168 // buffer is opaque are unaffected. If the colorTransform is
3169 // invertible, pixels where the A8 buffer are transparent have the
3170 // inverse applied to them so that the DPU will convert them back to
3171 // black. Test with an arbitrary, invertible matrix.
3172 .colorTransform = mat4(1, 0, 0, 2,
3173 3, 1, 2, 5,
3174 0, 5, 3, 0,
3175 0, 1, 0, 2),
3176 .deviceHandlesColorTransform = true,
3177 };
3178
3179 const auto redBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(255, 0, 0, 255));
3180 const renderengine::LayerSettings redLayer{
3181 .geometry.boundaries = rect.toFloatRect(),
3182 .source =
3183 renderengine::PixelSource{
3184 .buffer =
3185 renderengine::Buffer{
3186 .buffer = redBuffer,
3187 },
3188 },
3189 .alpha = 1.0f,
3190 };
3191 const renderengine::LayerSettings r8Layer{
3192 .geometry.boundaries = rect.toFloatRect(),
3193 .source =
3194 renderengine::PixelSource{
3195 .buffer =
3196 renderengine::Buffer{
3197 .buffer = r8Buffer,
3198 },
3199 },
3200 .alpha = 1.0f,
3201 };
3202
3203 std::vector<renderengine::LayerSettings> layers{redLayer, r8Layer};
3204 invokeDraw(display, layers);
3205
3206 expectBufferColor(Rect(1, 0, 2, 1), 255, 0, 0, 255); // Still red.
3207 expectBufferColor(Rect(0, 0, 1, 1), 0, 70, 0, 255);
3208}
Leon Scroggins III45be9182022-04-27 10:37:11 -04003209
3210TEST_P(RenderEngineTest, primeShaderCache) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003211 if (!GetParam()->typeSupported()) {
3212 GTEST_SKIP();
3213 }
Leon Scroggins III45be9182022-04-27 10:37:11 -04003214 initializeRenderEngine();
3215
3216 auto fut = mRE->primeCache();
3217 if (fut.valid()) {
3218 fut.wait();
3219 }
3220
Alec Mouri47bcb072023-08-15 02:02:49 +00003221 static constexpr int kMinimumExpectedShadersCompiled = 60;
Leon Scroggins III45be9182022-04-27 10:37:11 -04003222 ASSERT_GT(static_cast<skia::SkiaGLRenderEngine*>(mRE.get())->reportShadersCompiled(),
Alec Mouri47bcb072023-08-15 02:02:49 +00003223 kMinimumExpectedShadersCompiled);
Leon Scroggins III45be9182022-04-27 10:37:11 -04003224}
Derek Sollenbergerd3f60652021-06-11 15:34:36 -04003225} // namespace renderengine
Alec Mouri6e57f682018-09-29 20:45:08 -07003226} // namespace android
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08003227
3228// TODO(b/129481165): remove the #pragma below and fix conversion issues
Marin Shalamanovbed7fd32020-12-21 20:02:20 +01003229#pragma clang diagnostic pop // ignored "-Wconversion -Wextra"