blob: f3f2da8a0e52695c87134ffd38a4d5f143fdf966 [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;
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -0400112 virtual bool useColorManagement() const = 0;
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800113};
114
Ian Elliott1f0911e2022-09-09 16:31:47 -0600115class SkiaVkRenderEngineFactory : public RenderEngineFactory {
116public:
117 std::string name() override { return "SkiaVkRenderEngineFactory"; }
118
119 renderengine::RenderEngine::RenderEngineType type() {
120 return renderengine::RenderEngine::RenderEngineType::SKIA_VK;
121 }
122
123 std::unique_ptr<renderengine::RenderEngine> createRenderEngine() override {
124 std::unique_ptr<renderengine::RenderEngine> re = createSkiaVkRenderEngine();
125 return re;
126 }
127
128 std::unique_ptr<renderengine::skia::SkiaVkRenderEngine> createSkiaVkRenderEngine() {
129 renderengine::RenderEngineCreationArgs reCreationArgs =
130 renderengine::RenderEngineCreationArgs::Builder()
131 .setPixelFormat(static_cast<int>(ui::PixelFormat::RGBA_8888))
132 .setImageCacheSize(1)
133 .setUseColorManagerment(false)
134 .setEnableProtectedContext(false)
135 .setPrecacheToneMapperShaderOnly(false)
136 .setSupportsBackgroundBlur(true)
137 .setContextPriority(renderengine::RenderEngine::ContextPriority::MEDIUM)
138 .setRenderEngineType(type())
139 .setUseColorManagerment(useColorManagement())
140 .build();
141 return renderengine::skia::SkiaVkRenderEngine::create(reCreationArgs);
142 }
143
144 bool typeSupported() override {
145 return skia::SkiaVkRenderEngine::canSupportSkiaVkRenderEngine();
146 }
147 bool useColorManagement() const override { return false; }
148 void skip() { GTEST_SKIP(); }
149};
150
151class SkiaVkCMRenderEngineFactory : public SkiaVkRenderEngineFactory {
152public:
153 bool useColorManagement() const override { return true; }
154};
Alec Mouri0eab3e82020-12-08 18:10:27 -0800155class SkiaGLESRenderEngineFactory : public RenderEngineFactory {
156public:
Alec Mouric0aae732021-01-12 13:32:18 -0800157 std::string name() override { return "SkiaGLRenderEngineFactory"; }
Alec Mouri0eab3e82020-12-08 18:10:27 -0800158
Alec Mouric0aae732021-01-12 13:32:18 -0800159 renderengine::RenderEngine::RenderEngineType type() {
160 return renderengine::RenderEngine::RenderEngineType::SKIA_GL;
161 }
162
163 std::unique_ptr<renderengine::RenderEngine> createRenderEngine() override {
Alec Mouri0eab3e82020-12-08 18:10:27 -0800164 renderengine::RenderEngineCreationArgs reCreationArgs =
165 renderengine::RenderEngineCreationArgs::Builder()
166 .setPixelFormat(static_cast<int>(ui::PixelFormat::RGBA_8888))
167 .setImageCacheSize(1)
168 .setEnableProtectedContext(false)
169 .setPrecacheToneMapperShaderOnly(false)
170 .setSupportsBackgroundBlur(true)
171 .setContextPriority(renderengine::RenderEngine::ContextPriority::MEDIUM)
Alec Mouric0aae732021-01-12 13:32:18 -0800172 .setRenderEngineType(type())
Alec Mourid2bcbae2021-06-28 17:02:17 -0700173 .setUseColorManagerment(useColorManagement())
Alec Mouri0eab3e82020-12-08 18:10:27 -0800174 .build();
Alec Mouric0aae732021-01-12 13:32:18 -0800175 return renderengine::skia::SkiaGLRenderEngine::create(reCreationArgs);
Alec Mouri0eab3e82020-12-08 18:10:27 -0800176 }
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -0400177
Ian Elliott1f0911e2022-09-09 16:31:47 -0600178 bool typeSupported() override { return true; }
Alec Mourid2bcbae2021-06-28 17:02:17 -0700179 bool useColorManagement() const override { return false; }
Alec Mouri0eab3e82020-12-08 18:10:27 -0800180};
181
182class SkiaGLESCMRenderEngineFactory : public RenderEngineFactory {
183public:
Alec Mouric0aae732021-01-12 13:32:18 -0800184 std::string name() override { return "SkiaGLCMRenderEngineFactory"; }
Alec Mouri0eab3e82020-12-08 18:10:27 -0800185
Alec Mouric0aae732021-01-12 13:32:18 -0800186 renderengine::RenderEngine::RenderEngineType type() {
187 return renderengine::RenderEngine::RenderEngineType::SKIA_GL;
188 }
189
190 std::unique_ptr<renderengine::RenderEngine> createRenderEngine() override {
Alec Mouri0eab3e82020-12-08 18:10:27 -0800191 renderengine::RenderEngineCreationArgs reCreationArgs =
192 renderengine::RenderEngineCreationArgs::Builder()
193 .setPixelFormat(static_cast<int>(ui::PixelFormat::RGBA_8888))
194 .setImageCacheSize(1)
195 .setEnableProtectedContext(false)
196 .setPrecacheToneMapperShaderOnly(false)
197 .setSupportsBackgroundBlur(true)
198 .setContextPriority(renderengine::RenderEngine::ContextPriority::MEDIUM)
Alec Mouric0aae732021-01-12 13:32:18 -0800199 .setRenderEngineType(type())
Alec Mourid2bcbae2021-06-28 17:02:17 -0700200 .setUseColorManagerment(useColorManagement())
Alec Mouri0eab3e82020-12-08 18:10:27 -0800201 .build();
Alec Mouric0aae732021-01-12 13:32:18 -0800202 return renderengine::skia::SkiaGLRenderEngine::create(reCreationArgs);
Alec Mouri0eab3e82020-12-08 18:10:27 -0800203 }
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -0400204
Ian Elliott1f0911e2022-09-09 16:31:47 -0600205 bool typeSupported() override { return true; }
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -0400206 bool useColorManagement() const override { return true; }
Alec Mouri0eab3e82020-12-08 18:10:27 -0800207};
208
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800209class RenderEngineTest : public ::testing::TestWithParam<std::shared_ptr<RenderEngineFactory>> {
210public:
Alec Mouria90a5702021-04-16 16:36:21 +0000211 std::shared_ptr<renderengine::ExternalTexture> allocateDefaultBuffer() {
212 return std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800213 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -0700214 ExternalTexture>(sp<GraphicBuffer>::
215 make(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT,
216 HAL_PIXEL_FORMAT_RGBA_8888, 1,
217 GRALLOC_USAGE_SW_READ_OFTEN |
218 GRALLOC_USAGE_SW_WRITE_OFTEN |
219 GRALLOC_USAGE_HW_RENDER |
220 GRALLOC_USAGE_HW_TEXTURE,
221 "output"),
Alec Mouria90a5702021-04-16 16:36:21 +0000222 *mRE,
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800223 renderengine::impl::ExternalTexture::Usage::READABLE |
224 renderengine::impl::ExternalTexture::Usage::
225 WRITEABLE);
Alec Mouri6e57f682018-09-29 20:45:08 -0700226 }
227
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800228 // Allocates a 1x1 buffer to fill with a solid color
Alec Mouria90a5702021-04-16 16:36:21 +0000229 std::shared_ptr<renderengine::ExternalTexture> allocateSourceBuffer(uint32_t width,
230 uint32_t height) {
231 return std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800232 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -0700233 ExternalTexture>(sp<GraphicBuffer>::
234 make(width, height, HAL_PIXEL_FORMAT_RGBA_8888, 1,
235 GRALLOC_USAGE_SW_READ_OFTEN |
236 GRALLOC_USAGE_SW_WRITE_OFTEN |
237 GRALLOC_USAGE_HW_TEXTURE,
238 "input"),
Alec Mouria90a5702021-04-16 16:36:21 +0000239 *mRE,
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800240 renderengine::impl::ExternalTexture::Usage::READABLE |
241 renderengine::impl::ExternalTexture::Usage::
242 WRITEABLE);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800243 }
244
Alec Mouricdf6cbc2021-11-01 17:21:15 -0700245 std::shared_ptr<renderengine::ExternalTexture> allocateAndFillSourceBuffer(uint32_t width,
246 uint32_t height,
247 ubyte4 color) {
248 const auto buffer = allocateSourceBuffer(width, height);
249 uint8_t* pixels;
250 buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
251 reinterpret_cast<void**>(&pixels));
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -0500252 for (uint32_t j = 0; j < height; j++) {
253 uint8_t* dst = pixels + (buffer->getBuffer()->getStride() * j * 4);
254 for (uint32_t i = 0; i < width; i++) {
255 dst[0] = color.r;
256 dst[1] = color.g;
257 dst[2] = color.b;
258 dst[3] = color.a;
259 dst += 4;
260 }
261 }
Alec Mouricdf6cbc2021-11-01 17:21:15 -0700262 buffer->getBuffer()->unlock();
263 return buffer;
264 }
265
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -0500266 std::shared_ptr<renderengine::ExternalTexture> allocateR8Buffer(int width, int height) {
Ady Abrahamd11bade2022-08-01 16:18:03 -0700267 const auto kUsageFlags =
268 static_cast<uint64_t>(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
269 GRALLOC_USAGE_HW_TEXTURE);
270 auto buffer =
271 sp<GraphicBuffer>::make(static_cast<uint32_t>(width), static_cast<uint32_t>(height),
272 android::PIXEL_FORMAT_R_8, 1u, kUsageFlags, "r8");
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -0500273 if (buffer->initCheck() != 0) {
274 // Devices are not required to support R8.
275 return nullptr;
276 }
277 return std::make_shared<
278 renderengine::impl::ExternalTexture>(std::move(buffer), *mRE,
279 renderengine::impl::ExternalTexture::Usage::
280 READABLE);
281 }
282
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800283 RenderEngineTest() {
284 const ::testing::TestInfo* const test_info =
285 ::testing::UnitTest::GetInstance()->current_test_info();
286 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800287 }
Alec Mouri1089aed2018-10-25 21:33:57 -0700288
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800289 ~RenderEngineTest() {
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800290 if (WRITE_BUFFER_TO_FILE_ON_FAILURE && ::testing::Test::HasFailure()) {
291 writeBufferToFile("/data/texture_out_");
292 }
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800293 for (uint32_t texName : mTexNames) {
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800294 mRE->deleteTextures(1, &texName);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800295 }
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800296 const ::testing::TestInfo* const test_info =
297 ::testing::UnitTest::GetInstance()->current_test_info();
298 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800299 }
300
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800301 void writeBufferToFile(const char* basename) {
302 std::string filename(basename);
303 filename.append(::testing::UnitTest::GetInstance()->current_test_info()->name());
304 filename.append(".ppm");
305 std::ofstream file(filename.c_str(), std::ios::binary);
306 if (!file.is_open()) {
307 ALOGE("Unable to open file: %s", filename.c_str());
308 ALOGE("You may need to do: \"adb shell setenforce 0\" to enable "
309 "surfaceflinger to write debug images");
310 return;
311 }
312
Alec Mouri1089aed2018-10-25 21:33:57 -0700313 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +0000314 mBuffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
315 reinterpret_cast<void**>(&pixels));
Alec Mouri1089aed2018-10-25 21:33:57 -0700316
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800317 file << "P6\n";
Alec Mouria90a5702021-04-16 16:36:21 +0000318 file << mBuffer->getBuffer()->getWidth() << "\n";
319 file << mBuffer->getBuffer()->getHeight() << "\n";
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800320 file << 255 << "\n";
321
Alec Mouria90a5702021-04-16 16:36:21 +0000322 std::vector<uint8_t> outBuffer(mBuffer->getBuffer()->getWidth() *
323 mBuffer->getBuffer()->getHeight() * 3);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800324 auto outPtr = reinterpret_cast<uint8_t*>(outBuffer.data());
325
Alec Mouria90a5702021-04-16 16:36:21 +0000326 for (int32_t j = 0; j < mBuffer->getBuffer()->getHeight(); j++) {
327 const uint8_t* src = pixels + (mBuffer->getBuffer()->getStride() * j) * 4;
328 for (int32_t i = 0; i < mBuffer->getBuffer()->getWidth(); i++) {
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800329 // Only copy R, G and B components
330 outPtr[0] = src[0];
331 outPtr[1] = src[1];
332 outPtr[2] = src[2];
333 outPtr += 3;
334
335 src += 4;
336 }
337 }
338 file.write(reinterpret_cast<char*>(outBuffer.data()), outBuffer.size());
Alec Mouria90a5702021-04-16 16:36:21 +0000339 mBuffer->getBuffer()->unlock();
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800340 }
341
342 void expectBufferColor(const Region& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
343 size_t c;
344 Rect const* rect = region.getArray(&c);
345 for (size_t i = 0; i < c; i++, rect++) {
346 expectBufferColor(*rect, r, g, b, a);
347 }
348 }
349
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -0400350 void expectBufferColor(const Point& point, uint8_t r, uint8_t g, uint8_t b, uint8_t a,
351 uint8_t tolerance = 0) {
352 expectBufferColor(Rect(point.x, point.y, point.x + 1, point.y + 1), r, g, b, a, tolerance);
353 }
354
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800355 void expectBufferColor(const Rect& rect, uint8_t r, uint8_t g, uint8_t b, uint8_t a,
356 uint8_t tolerance = 0) {
Alec Mouri4049b532021-10-15 20:59:33 -0700357 auto generator = [=](Point) { return ubyte4(r, g, b, a); };
358 expectBufferColor(rect, generator, tolerance);
359 }
360
361 using ColorGenerator = std::function<ubyte4(Point location)>;
362
363 void expectBufferColor(const Rect& rect, ColorGenerator generator, uint8_t tolerance = 0) {
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800364 auto colorCompare = [tolerance](const uint8_t* colorA, const uint8_t* colorB) {
365 auto colorBitCompare = [tolerance](uint8_t a, uint8_t b) {
366 uint8_t tmp = a >= b ? a - b : b - a;
367 return tmp <= tolerance;
368 };
369 return std::equal(colorA, colorA + 4, colorB, colorBitCompare);
Alec Mouri1089aed2018-10-25 21:33:57 -0700370 };
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800371
Alec Mouri4049b532021-10-15 20:59:33 -0700372 expectBufferColor(rect, generator, colorCompare);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800373 }
374
Alec Mouri4049b532021-10-15 20:59:33 -0700375 void expectBufferColor(const Rect& region, ColorGenerator generator,
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800376 std::function<bool(const uint8_t* a, const uint8_t* b)> colorCompare) {
377 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +0000378 mBuffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
379 reinterpret_cast<void**>(&pixels));
Alec Mouri1089aed2018-10-25 21:33:57 -0700380 int32_t maxFails = 10;
381 int32_t fails = 0;
382 for (int32_t j = 0; j < region.getHeight(); j++) {
Alec Mouria90a5702021-04-16 16:36:21 +0000383 const uint8_t* src = pixels +
384 (mBuffer->getBuffer()->getStride() * (region.top + j) + region.left) * 4;
Alec Mouri1089aed2018-10-25 21:33:57 -0700385 for (int32_t i = 0; i < region.getWidth(); i++) {
Alec Mouri4049b532021-10-15 20:59:33 -0700386 const auto location = Point(region.left + i, region.top + j);
387 const ubyte4 colors = generator(location);
388 const uint8_t expected[4] = {colors.r, colors.g, colors.b, colors.a};
389 bool colorMatches = colorCompare(src, expected);
390 EXPECT_TRUE(colorMatches)
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -0400391 << GetParam()->name().c_str() << ": "
Alec Mouri4049b532021-10-15 20:59:33 -0700392 << "pixel @ (" << location.x << ", " << location.y << "): "
393 << "expected (" << static_cast<uint32_t>(colors.r) << ", "
394 << static_cast<uint32_t>(colors.g) << ", "
395 << static_cast<uint32_t>(colors.b) << ", "
396 << static_cast<uint32_t>(colors.a) << "), "
Alec Mouri1089aed2018-10-25 21:33:57 -0700397 << "got (" << static_cast<uint32_t>(src[0]) << ", "
398 << static_cast<uint32_t>(src[1]) << ", " << static_cast<uint32_t>(src[2])
399 << ", " << static_cast<uint32_t>(src[3]) << ")";
400 src += 4;
Alec Mouri4049b532021-10-15 20:59:33 -0700401 if (!colorMatches && ++fails >= maxFails) {
Alec Mouri1089aed2018-10-25 21:33:57 -0700402 break;
403 }
404 }
405 if (fails >= maxFails) {
406 break;
407 }
408 }
Alec Mouria90a5702021-04-16 16:36:21 +0000409 mBuffer->getBuffer()->unlock();
Alec Mouri1089aed2018-10-25 21:33:57 -0700410 }
411
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800412 void expectAlpha(const Rect& rect, uint8_t a) {
Alec Mouri4049b532021-10-15 20:59:33 -0700413 auto generator = [=](Point) { return ubyte4(0, 0, 0, a); };
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800414 auto colorCompare = [](const uint8_t* colorA, const uint8_t* colorB) {
415 return colorA[3] == colorB[3];
416 };
Alec Mouri4049b532021-10-15 20:59:33 -0700417 expectBufferColor(rect, generator, colorCompare);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800418 }
419
420 void expectShadowColor(const renderengine::LayerSettings& castingLayer,
421 const renderengine::ShadowSettings& shadow, const ubyte4& casterColor,
422 const ubyte4& backgroundColor) {
423 const Rect casterRect(castingLayer.geometry.boundaries);
424 Region casterRegion = Region(casterRect);
Vishnu Nair50c0afe2022-07-11 15:04:07 -0700425 const float casterCornerRadius = (castingLayer.geometry.roundedCornersRadius.x +
426 castingLayer.geometry.roundedCornersRadius.y) /
427 2.0;
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800428 if (casterCornerRadius > 0.0f) {
429 // ignore the corners if a corner radius is set
430 Rect cornerRect(casterCornerRadius, casterCornerRadius);
431 casterRegion.subtractSelf(cornerRect.offsetTo(casterRect.left, casterRect.top));
432 casterRegion.subtractSelf(
433 cornerRect.offsetTo(casterRect.right - casterCornerRadius, casterRect.top));
434 casterRegion.subtractSelf(
435 cornerRect.offsetTo(casterRect.left, casterRect.bottom - casterCornerRadius));
436 casterRegion.subtractSelf(cornerRect.offsetTo(casterRect.right - casterCornerRadius,
437 casterRect.bottom - casterCornerRadius));
438 }
439
440 const float shadowInset = shadow.length * -1.0f;
441 const Rect casterWithShadow =
442 Rect(casterRect).inset(shadowInset, shadowInset, shadowInset, shadowInset);
443 const Region shadowRegion = Region(casterWithShadow).subtractSelf(casterRect);
444 const Region backgroundRegion = Region(fullscreenRect()).subtractSelf(casterWithShadow);
445
446 // verify casting layer
447 expectBufferColor(casterRegion, casterColor.r, casterColor.g, casterColor.b, casterColor.a);
448
449 // verify shadows by testing just the alpha since its difficult to validate the shadow color
450 size_t c;
451 Rect const* r = shadowRegion.getArray(&c);
452 for (size_t i = 0; i < c; i++, r++) {
453 expectAlpha(*r, 255);
454 }
455
456 // verify background
457 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
458 backgroundColor.a);
459 }
460
Alec Mouribd17b3b2020-12-17 11:08:30 -0800461 void expectShadowColorWithoutCaster(const FloatRect& casterBounds,
462 const renderengine::ShadowSettings& shadow,
463 const ubyte4& backgroundColor) {
464 const float shadowInset = shadow.length * -1.0f;
465 const Rect casterRect(casterBounds);
466 const Rect shadowRect =
467 Rect(casterRect).inset(shadowInset, shadowInset, shadowInset, shadowInset);
468
469 const Region backgroundRegion =
470 Region(fullscreenRect()).subtractSelf(casterRect).subtractSelf(shadowRect);
471
472 expectAlpha(shadowRect, 255);
473 // (0, 0, 0) fill on the bounds of the layer should be ignored.
474 expectBufferColor(casterRect, 255, 255, 255, 255, 254);
475
476 // verify background
477 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
478 backgroundColor.a);
479 }
480
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800481 static renderengine::ShadowSettings getShadowSettings(const vec2& casterPos, float shadowLength,
482 bool casterIsTranslucent) {
483 renderengine::ShadowSettings shadow;
484 shadow.ambientColor = {0.0f, 0.0f, 0.0f, 0.039f};
485 shadow.spotColor = {0.0f, 0.0f, 0.0f, 0.19f};
486 shadow.lightPos = vec3(casterPos.x, casterPos.y, 0);
487 shadow.lightRadius = 0.0f;
488 shadow.length = shadowLength;
489 shadow.casterIsTranslucent = casterIsTranslucent;
490 return shadow;
491 }
492
Alec Mouri1089aed2018-10-25 21:33:57 -0700493 static Rect fullscreenRect() { return Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT); }
494
495 static Rect offsetRect() {
496 return Rect(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_WIDTH,
497 DEFAULT_DISPLAY_HEIGHT);
498 }
499
500 static Rect offsetRectAtZero() {
501 return Rect(DEFAULT_DISPLAY_WIDTH - DEFAULT_DISPLAY_OFFSET,
502 DEFAULT_DISPLAY_HEIGHT - DEFAULT_DISPLAY_OFFSET);
503 }
504
Sally Qi59a9f502021-10-12 18:53:23 +0000505 void invokeDraw(const renderengine::DisplaySettings& settings,
506 const std::vector<renderengine::LayerSettings>& layers) {
Patrick Williams2e9748f2022-08-09 22:48:18 +0000507 ftl::Future<FenceResult> future =
Sally Qi4cabdd02021-08-05 16:45:57 -0700508 mRE->drawLayers(settings, layers, mBuffer, true, base::unique_fd());
Patrick Williams2e9748f2022-08-09 22:48:18 +0000509 ASSERT_TRUE(future.valid());
Sally Qi59a9f502021-10-12 18:53:23 +0000510
Patrick Williams2e9748f2022-08-09 22:48:18 +0000511 auto result = future.get();
512 ASSERT_TRUE(result.ok());
Alec Mouri1089aed2018-10-25 21:33:57 -0700513
Patrick Williams2e9748f2022-08-09 22:48:18 +0000514 auto fence = result.value();
515 fence->waitForever(LOG_TAG);
Alec Mouri1089aed2018-10-25 21:33:57 -0700516 }
517
Alec Mourid43ccab2019-03-13 12:23:45 -0700518 void drawEmptyLayers() {
Alec Mouri6e57f682018-09-29 20:45:08 -0700519 renderengine::DisplaySettings settings;
Sally Qi59a9f502021-10-12 18:53:23 +0000520 std::vector<renderengine::LayerSettings> layers;
Alec Mouric0aae732021-01-12 13:32:18 -0800521 invokeDraw(settings, layers);
Alec Mouri6e57f682018-09-29 20:45:08 -0700522 }
523
Alec Mouri1089aed2018-10-25 21:33:57 -0700524 template <typename SourceVariant>
525 void fillBuffer(half r, half g, half b, half a);
526
527 template <typename SourceVariant>
528 void fillRedBuffer();
529
530 template <typename SourceVariant>
531 void fillGreenBuffer();
532
533 template <typename SourceVariant>
534 void fillBlueBuffer();
535
536 template <typename SourceVariant>
537 void fillRedTransparentBuffer();
538
539 template <typename SourceVariant>
540 void fillRedOffsetBuffer();
541
542 template <typename SourceVariant>
543 void fillBufferPhysicalOffset();
544
545 template <typename SourceVariant>
Alec Mouri5a6d8572020-03-23 23:56:15 -0700546 void fillBufferCheckers(uint32_t rotation);
Alec Mouri1089aed2018-10-25 21:33:57 -0700547
548 template <typename SourceVariant>
549 void fillBufferCheckersRotate0();
550
551 template <typename SourceVariant>
552 void fillBufferCheckersRotate90();
553
554 template <typename SourceVariant>
555 void fillBufferCheckersRotate180();
556
557 template <typename SourceVariant>
558 void fillBufferCheckersRotate270();
559
560 template <typename SourceVariant>
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800561 void fillBufferWithLayerTransform();
562
563 template <typename SourceVariant>
Alec Mouri1089aed2018-10-25 21:33:57 -0700564 void fillBufferLayerTransform();
565
566 template <typename SourceVariant>
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800567 void fillBufferWithColorTransform();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800568
569 template <typename SourceVariant>
Alec Mouri1089aed2018-10-25 21:33:57 -0700570 void fillBufferColorTransform();
571
Alec Mouri7c94edb2018-12-03 21:23:26 -0800572 template <typename SourceVariant>
Sally Qi2019fd22021-11-22 10:19:04 -0800573 void fillBufferWithColorTransformAndSourceDataspace(const ui::Dataspace sourceDataspace);
574
575 template <typename SourceVariant>
576 void fillBufferColorTransformAndSourceDataspace();
577
578 template <typename SourceVariant>
579 void fillBufferWithColorTransformAndOutputDataspace(const ui::Dataspace outputDataspace);
580
581 template <typename SourceVariant>
582 void fillBufferColorTransformAndOutputDataspace();
583
584 template <typename SourceVariant>
KaiChieh Chuangda2845c2020-12-14 16:49:38 +0800585 void fillBufferWithColorTransformZeroLayerAlpha();
586
587 template <typename SourceVariant>
588 void fillBufferColorTransformZeroLayerAlpha();
589
590 template <typename SourceVariant>
Alec Mouri7c94edb2018-12-03 21:23:26 -0800591 void fillRedBufferWithRoundedCorners();
592
593 template <typename SourceVariant>
594 void fillBufferWithRoundedCorners();
595
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000596 template <typename SourceVariant>
Lucas Dupin19c8f0e2019-11-25 17:55:44 -0800597 void fillBufferAndBlurBackground();
598
599 template <typename SourceVariant>
Alec Mourie8489fd2021-04-29 16:08:56 -0700600 void fillSmallLayerAndBlurBackground();
601
602 template <typename SourceVariant>
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000603 void overlayCorners();
604
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800605 void fillRedBufferTextureTransform();
606
607 void fillBufferTextureTransform();
608
609 void fillRedBufferWithPremultiplyAlpha();
610
611 void fillBufferWithPremultiplyAlpha();
612
613 void fillRedBufferWithoutPremultiplyAlpha();
614
615 void fillBufferWithoutPremultiplyAlpha();
616
Alec Mouriac335532018-11-12 15:01:33 -0800617 void fillGreenColorBufferThenClearRegion();
618
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800619 template <typename SourceVariant>
620 void drawShadow(const renderengine::LayerSettings& castingLayer,
621 const renderengine::ShadowSettings& shadow, const ubyte4& casterColor,
622 const ubyte4& backgroundColor);
623
Alec Mouribd17b3b2020-12-17 11:08:30 -0800624 void drawShadowWithoutCaster(const FloatRect& castingBounds,
625 const renderengine::ShadowSettings& shadow,
626 const ubyte4& backgroundColor);
627
Alec Mouri5a493722022-01-26 16:43:02 -0800628 // Tonemaps grey values from sourceDataspace -> Display P3 and checks that GPU and CPU
629 // implementations are identical Also implicitly checks that the injected tonemap shader
630 // compiles
631 void tonemap(ui::Dataspace sourceDataspace, std::function<vec3(vec3)> eotf,
632 std::function<vec3(vec3, float)> scaleOotf);
633
Alec Mouric0aae732021-01-12 13:32:18 -0800634 void initializeRenderEngine();
635
636 std::unique_ptr<renderengine::RenderEngine> mRE;
Alec Mouria90a5702021-04-16 16:36:21 +0000637 std::shared_ptr<renderengine::ExternalTexture> mBuffer;
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800638
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800639 std::vector<uint32_t> mTexNames;
Alec Mouri6e57f682018-09-29 20:45:08 -0700640};
641
Alec Mouric0aae732021-01-12 13:32:18 -0800642void RenderEngineTest::initializeRenderEngine() {
643 const auto& renderEngineFactory = GetParam();
Alec Mouric16974e2022-09-13 17:35:48 +0000644 mRE = renderEngineFactory->createRenderEngine();
Alec Mouria90a5702021-04-16 16:36:21 +0000645 mBuffer = allocateDefaultBuffer();
Alec Mouric0aae732021-01-12 13:32:18 -0800646}
647
Alec Mouri1089aed2018-10-25 21:33:57 -0700648struct ColorSourceVariant {
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800649 static void fillColor(renderengine::LayerSettings& layer, half r, half g, half b,
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800650 RenderEngineTest* /*fixture*/) {
Alec Mouri1089aed2018-10-25 21:33:57 -0700651 layer.source.solidColor = half3(r, g, b);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800652 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700653 }
654};
655
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800656struct RelaxOpaqueBufferVariant {
657 static void setOpaqueBit(renderengine::LayerSettings& layer) {
658 layer.source.buffer.isOpaque = false;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800659 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800660 }
661
662 static uint8_t getAlphaChannel() { return 255; }
663};
664
665struct ForceOpaqueBufferVariant {
666 static void setOpaqueBit(renderengine::LayerSettings& layer) {
667 layer.source.buffer.isOpaque = true;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800668 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800669 }
670
671 static uint8_t getAlphaChannel() {
672 // The isOpaque bit will override the alpha channel, so this should be
673 // arbitrary.
Alec Mouric0aae732021-01-12 13:32:18 -0800674 return 50;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800675 }
676};
677
678template <typename OpaquenessVariant>
679struct BufferSourceVariant {
680 static void fillColor(renderengine::LayerSettings& layer, half r, half g, half b,
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800681 RenderEngineTest* fixture) {
Alec Mouria90a5702021-04-16 16:36:21 +0000682 const auto buf = fixture->allocateSourceBuffer(1, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800683 uint32_t texName;
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800684 fixture->mRE->genTextures(1, &texName);
685 fixture->mTexNames.push_back(texName);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800686
687 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +0000688 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
689 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800690
Alec Mouria90a5702021-04-16 16:36:21 +0000691 for (int32_t j = 0; j < buf->getBuffer()->getHeight(); j++) {
692 uint8_t* iter = pixels + (buf->getBuffer()->getStride() * j) * 4;
693 for (int32_t i = 0; i < buf->getBuffer()->getWidth(); i++) {
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800694 iter[0] = uint8_t(r * 255);
695 iter[1] = uint8_t(g * 255);
696 iter[2] = uint8_t(b * 255);
697 iter[3] = OpaquenessVariant::getAlphaChannel();
698 iter += 4;
699 }
700 }
701
Alec Mouria90a5702021-04-16 16:36:21 +0000702 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800703
704 layer.source.buffer.buffer = buf;
705 layer.source.buffer.textureName = texName;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800706 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800707 OpaquenessVariant::setOpaqueBit(layer);
708 }
709};
710
Alec Mouri1089aed2018-10-25 21:33:57 -0700711template <typename SourceVariant>
712void RenderEngineTest::fillBuffer(half r, half g, half b, half a) {
713 renderengine::DisplaySettings settings;
714 settings.physicalDisplay = fullscreenRect();
715 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800716 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700717
Sally Qi59a9f502021-10-12 18:53:23 +0000718 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700719
720 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800721 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700722 layer.geometry.boundaries = fullscreenRect().toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800723 SourceVariant::fillColor(layer, r, g, b, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700724 layer.alpha = a;
725
Sally Qi59a9f502021-10-12 18:53:23 +0000726 layers.push_back(layer);
Alec Mouri1089aed2018-10-25 21:33:57 -0700727
Alec Mouric0aae732021-01-12 13:32:18 -0800728 invokeDraw(settings, layers);
Alec Mouri1089aed2018-10-25 21:33:57 -0700729}
730
731template <typename SourceVariant>
732void RenderEngineTest::fillRedBuffer() {
733 fillBuffer<SourceVariant>(1.0f, 0.0f, 0.0f, 1.0f);
734 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
735}
736
737template <typename SourceVariant>
738void RenderEngineTest::fillGreenBuffer() {
739 fillBuffer<SourceVariant>(0.0f, 1.0f, 0.0f, 1.0f);
740 expectBufferColor(fullscreenRect(), 0, 255, 0, 255);
741}
742
743template <typename SourceVariant>
744void RenderEngineTest::fillBlueBuffer() {
745 fillBuffer<SourceVariant>(0.0f, 0.0f, 1.0f, 1.0f);
746 expectBufferColor(fullscreenRect(), 0, 0, 255, 255);
747}
748
749template <typename SourceVariant>
750void RenderEngineTest::fillRedTransparentBuffer() {
751 fillBuffer<SourceVariant>(1.0f, 0.0f, 0.0f, .2f);
752 expectBufferColor(fullscreenRect(), 51, 0, 0, 51);
753}
754
755template <typename SourceVariant>
756void RenderEngineTest::fillRedOffsetBuffer() {
757 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800758 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700759 settings.physicalDisplay = offsetRect();
760 settings.clip = offsetRectAtZero();
761
Sally Qi59a9f502021-10-12 18:53:23 +0000762 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700763
764 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800765 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700766 layer.geometry.boundaries = offsetRectAtZero().toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800767 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700768 layer.alpha = 1.0f;
769
Sally Qi59a9f502021-10-12 18:53:23 +0000770 layers.push_back(layer);
Alec Mouric0aae732021-01-12 13:32:18 -0800771 invokeDraw(settings, layers);
Alec Mouri1089aed2018-10-25 21:33:57 -0700772}
773
774template <typename SourceVariant>
775void RenderEngineTest::fillBufferPhysicalOffset() {
776 fillRedOffsetBuffer<SourceVariant>();
777
778 expectBufferColor(Rect(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_WIDTH,
779 DEFAULT_DISPLAY_HEIGHT),
780 255, 0, 0, 255);
781 Rect offsetRegionLeft(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_HEIGHT);
782 Rect offsetRegionTop(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_OFFSET);
783
784 expectBufferColor(offsetRegionLeft, 0, 0, 0, 0);
785 expectBufferColor(offsetRegionTop, 0, 0, 0, 0);
786}
787
788template <typename SourceVariant>
Alec Mouri5a6d8572020-03-23 23:56:15 -0700789void RenderEngineTest::fillBufferCheckers(uint32_t orientationFlag) {
Alec Mouri1089aed2018-10-25 21:33:57 -0700790 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800791 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700792 settings.physicalDisplay = fullscreenRect();
793 // Here logical space is 2x2
794 settings.clip = Rect(2, 2);
Alec Mouri5a6d8572020-03-23 23:56:15 -0700795 settings.orientation = orientationFlag;
Alec Mouri1089aed2018-10-25 21:33:57 -0700796
Sally Qi59a9f502021-10-12 18:53:23 +0000797 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700798
799 renderengine::LayerSettings layerOne;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800800 layerOne.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700801 Rect rectOne(0, 0, 1, 1);
802 layerOne.geometry.boundaries = rectOne.toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800803 SourceVariant::fillColor(layerOne, 1.0f, 0.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700804 layerOne.alpha = 1.0f;
805
806 renderengine::LayerSettings layerTwo;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800807 layerTwo.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700808 Rect rectTwo(0, 1, 1, 2);
809 layerTwo.geometry.boundaries = rectTwo.toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800810 SourceVariant::fillColor(layerTwo, 0.0f, 1.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700811 layerTwo.alpha = 1.0f;
812
813 renderengine::LayerSettings layerThree;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800814 layerThree.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700815 Rect rectThree(1, 0, 2, 1);
816 layerThree.geometry.boundaries = rectThree.toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800817 SourceVariant::fillColor(layerThree, 0.0f, 0.0f, 1.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700818 layerThree.alpha = 1.0f;
819
Sally Qi59a9f502021-10-12 18:53:23 +0000820 layers.push_back(layerOne);
821 layers.push_back(layerTwo);
822 layers.push_back(layerThree);
Alec Mouri1089aed2018-10-25 21:33:57 -0700823
Alec Mouric0aae732021-01-12 13:32:18 -0800824 invokeDraw(settings, layers);
Alec Mouri1089aed2018-10-25 21:33:57 -0700825}
826
827template <typename SourceVariant>
828void RenderEngineTest::fillBufferCheckersRotate0() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700829 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_0);
Alec Mouri1089aed2018-10-25 21:33:57 -0700830 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0,
831 255);
832 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
833 DEFAULT_DISPLAY_HEIGHT / 2),
834 0, 0, 255, 255);
835 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
836 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
837 0, 0, 0, 0);
838 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
839 DEFAULT_DISPLAY_HEIGHT),
840 0, 255, 0, 255);
841}
842
843template <typename SourceVariant>
844void RenderEngineTest::fillBufferCheckersRotate90() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700845 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_90);
Alec Mouri1089aed2018-10-25 21:33:57 -0700846 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 255, 0,
847 255);
848 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
849 DEFAULT_DISPLAY_HEIGHT / 2),
850 255, 0, 0, 255);
851 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
852 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
853 0, 0, 255, 255);
854 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
855 DEFAULT_DISPLAY_HEIGHT),
856 0, 0, 0, 0);
857}
858
859template <typename SourceVariant>
860void RenderEngineTest::fillBufferCheckersRotate180() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700861 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_180);
Alec Mouri1089aed2018-10-25 21:33:57 -0700862 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 0,
863 0);
864 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
865 DEFAULT_DISPLAY_HEIGHT / 2),
866 0, 255, 0, 255);
867 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
868 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
869 255, 0, 0, 255);
870 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
871 DEFAULT_DISPLAY_HEIGHT),
872 0, 0, 255, 255);
873}
874
875template <typename SourceVariant>
876void RenderEngineTest::fillBufferCheckersRotate270() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700877 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_270);
Alec Mouri1089aed2018-10-25 21:33:57 -0700878 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 255,
879 255);
880 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
881 DEFAULT_DISPLAY_HEIGHT / 2),
882 0, 0, 0, 0);
883 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
884 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
885 0, 255, 0, 255);
886 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
887 DEFAULT_DISPLAY_HEIGHT),
888 255, 0, 0, 255);
889}
890
891template <typename SourceVariant>
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800892void RenderEngineTest::fillBufferWithLayerTransform() {
Alec Mouri1089aed2018-10-25 21:33:57 -0700893 renderengine::DisplaySettings settings;
894 settings.physicalDisplay = fullscreenRect();
895 // Here logical space is 2x2
896 settings.clip = Rect(2, 2);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800897 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700898
Sally Qi59a9f502021-10-12 18:53:23 +0000899 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700900
901 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800902 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700903 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
904 // Translate one pixel diagonally
905 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 -0800906 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700907 layer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
908 layer.alpha = 1.0f;
909
Sally Qi59a9f502021-10-12 18:53:23 +0000910 layers.push_back(layer);
Alec Mouri1089aed2018-10-25 21:33:57 -0700911
Alec Mouric0aae732021-01-12 13:32:18 -0800912 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800913}
Alec Mouri1089aed2018-10-25 21:33:57 -0700914
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800915template <typename SourceVariant>
916void RenderEngineTest::fillBufferLayerTransform() {
917 fillBufferWithLayerTransform<SourceVariant>();
Alec Mouri1089aed2018-10-25 21:33:57 -0700918 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 0, 0);
919 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
920 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
921 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
922 255, 0, 0, 255);
923}
924
925template <typename SourceVariant>
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800926void RenderEngineTest::fillBufferWithColorTransform() {
Alec Mouri1089aed2018-10-25 21:33:57 -0700927 renderengine::DisplaySettings settings;
928 settings.physicalDisplay = fullscreenRect();
929 settings.clip = Rect(1, 1);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800930 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700931
Sally Qi59a9f502021-10-12 18:53:23 +0000932 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700933
934 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800935 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700936 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800937 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700938 layer.alpha = 1.0f;
939
940 // construct a fake color matrix
941 // annihilate green and blue channels
KaiChieh Chuang436fc192020-09-07 13:48:42 +0800942 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
Alec Mouri1089aed2018-10-25 21:33:57 -0700943 // set red channel to red + green
944 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
945
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800946 layer.alpha = 1.0f;
947 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
948
Sally Qi59a9f502021-10-12 18:53:23 +0000949 layers.push_back(layer);
Alec Mouri1089aed2018-10-25 21:33:57 -0700950
Alec Mouric0aae732021-01-12 13:32:18 -0800951 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800952}
Alec Mouri1089aed2018-10-25 21:33:57 -0700953
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800954template <typename SourceVariant>
Sally Qi2019fd22021-11-22 10:19:04 -0800955void RenderEngineTest::fillBufferWithColorTransformAndSourceDataspace(
956 const ui::Dataspace sourceDataspace) {
957 renderengine::DisplaySettings settings;
958 settings.physicalDisplay = fullscreenRect();
959 settings.clip = Rect(1, 1);
960 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
961
962 std::vector<renderengine::LayerSettings> layers;
963
964 renderengine::LayerSettings layer;
Sally Qi2019fd22021-11-22 10:19:04 -0800965 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
966 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
Alec Mouric16974e2022-09-13 17:35:48 +0000967 layer.sourceDataspace = sourceDataspace;
Sally Qi2019fd22021-11-22 10:19:04 -0800968 layer.alpha = 1.0f;
969
970 // construct a fake color matrix
971 // annihilate green and blue channels
972 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
973 // set red channel to red + green
974 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
975
976 layer.alpha = 1.0f;
977 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
978
979 layers.push_back(layer);
980
981 invokeDraw(settings, layers);
982}
983
984template <typename SourceVariant>
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800985void RenderEngineTest::fillBufferColorTransform() {
986 fillBufferWithColorTransform<SourceVariant>();
KaiChieh Chuang436fc192020-09-07 13:48:42 +0800987 expectBufferColor(fullscreenRect(), 172, 0, 0, 255, 1);
988}
989
990template <typename SourceVariant>
Sally Qi2019fd22021-11-22 10:19:04 -0800991void RenderEngineTest::fillBufferColorTransformAndSourceDataspace() {
992 unordered_map<ui::Dataspace, ubyte4> dataspaceToColorMap;
Alec Mouric16974e2022-09-13 17:35:48 +0000993 dataspaceToColorMap[ui::Dataspace::V0_BT709] = {77, 0, 0, 255};
994 dataspaceToColorMap[ui::Dataspace::BT2020] = {101, 0, 0, 255};
995 dataspaceToColorMap[ui::Dataspace::ADOBE_RGB] = {75, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -0800996 ui::Dataspace customizedDataspace = static_cast<ui::Dataspace>(
997 ui::Dataspace::STANDARD_BT709 | ui::Dataspace::TRANSFER_GAMMA2_2 |
998 ui::Dataspace::RANGE_FULL);
Alec Mouric16974e2022-09-13 17:35:48 +0000999 dataspaceToColorMap[customizedDataspace] = {61, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -08001000 for (const auto& [sourceDataspace, color] : dataspaceToColorMap) {
1001 fillBufferWithColorTransformAndSourceDataspace<SourceVariant>(sourceDataspace);
1002 expectBufferColor(fullscreenRect(), color.r, color.g, color.b, color.a, 1);
1003 }
1004}
1005
1006template <typename SourceVariant>
1007void RenderEngineTest::fillBufferWithColorTransformAndOutputDataspace(
1008 const ui::Dataspace outputDataspace) {
1009 renderengine::DisplaySettings settings;
1010 settings.physicalDisplay = fullscreenRect();
1011 settings.clip = Rect(1, 1);
1012 settings.outputDataspace = outputDataspace;
1013
1014 std::vector<renderengine::LayerSettings> layers;
1015
1016 renderengine::LayerSettings layer;
1017 layer.sourceDataspace = ui::Dataspace::V0_SCRGB_LINEAR;
1018 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1019 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
1020 layer.alpha = 1.0f;
1021
1022 // construct a fake color matrix
1023 // annihilate green and blue channels
1024 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
1025 // set red channel to red + green
1026 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
1027
1028 layer.alpha = 1.0f;
1029 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1030
1031 layers.push_back(layer);
1032
1033 invokeDraw(settings, layers);
1034}
1035
1036template <typename SourceVariant>
1037void RenderEngineTest::fillBufferColorTransformAndOutputDataspace() {
1038 unordered_map<ui::Dataspace, ubyte4> dataspaceToColorMap;
Alec Mouric16974e2022-09-13 17:35:48 +00001039 dataspaceToColorMap[ui::Dataspace::V0_BT709] = {198, 0, 0, 255};
1040 dataspaceToColorMap[ui::Dataspace::BT2020] = {187, 0, 0, 255};
1041 dataspaceToColorMap[ui::Dataspace::ADOBE_RGB] = {192, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -08001042 ui::Dataspace customizedDataspace = static_cast<ui::Dataspace>(
1043 ui::Dataspace::STANDARD_BT709 | ui::Dataspace::TRANSFER_GAMMA2_6 |
1044 ui::Dataspace::RANGE_FULL);
Alec Mouric16974e2022-09-13 17:35:48 +00001045 dataspaceToColorMap[customizedDataspace] = {205, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -08001046 for (const auto& [outputDataspace, color] : dataspaceToColorMap) {
1047 fillBufferWithColorTransformAndOutputDataspace<SourceVariant>(outputDataspace);
1048 expectBufferColor(fullscreenRect(), color.r, color.g, color.b, color.a, 1);
1049 }
1050}
1051
1052template <typename SourceVariant>
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001053void RenderEngineTest::fillBufferWithColorTransformZeroLayerAlpha() {
1054 renderengine::DisplaySettings settings;
1055 settings.physicalDisplay = fullscreenRect();
1056 settings.clip = Rect(1, 1);
1057
Sally Qi59a9f502021-10-12 18:53:23 +00001058 std::vector<renderengine::LayerSettings> layers;
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001059
1060 renderengine::LayerSettings layer;
1061 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1062 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
1063 layer.alpha = 0;
1064
1065 // construct a fake color matrix
1066 // simple inverse color
1067 settings.colorTransform = mat4(-1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 1, 1, 1, 1);
1068
1069 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1070
Sally Qi59a9f502021-10-12 18:53:23 +00001071 layers.push_back(layer);
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001072
Alec Mouric0aae732021-01-12 13:32:18 -08001073 invokeDraw(settings, layers);
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001074}
1075
1076template <typename SourceVariant>
1077void RenderEngineTest::fillBufferColorTransformZeroLayerAlpha() {
1078 fillBufferWithColorTransformZeroLayerAlpha<SourceVariant>();
1079 expectBufferColor(fullscreenRect(), 0, 0, 0, 0);
1080}
1081
1082template <typename SourceVariant>
Alec Mouri7c94edb2018-12-03 21:23:26 -08001083void RenderEngineTest::fillRedBufferWithRoundedCorners() {
1084 renderengine::DisplaySettings settings;
1085 settings.physicalDisplay = fullscreenRect();
1086 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001087 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri7c94edb2018-12-03 21:23:26 -08001088
Sally Qi59a9f502021-10-12 18:53:23 +00001089 std::vector<renderengine::LayerSettings> layers;
Alec Mouri7c94edb2018-12-03 21:23:26 -08001090
1091 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001092 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri7c94edb2018-12-03 21:23:26 -08001093 layer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07001094 layer.geometry.roundedCornersRadius = {5.0f, 5.0f};
Alec Mouri7c94edb2018-12-03 21:23:26 -08001095 layer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
1096 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
1097 layer.alpha = 1.0f;
1098
Sally Qi59a9f502021-10-12 18:53:23 +00001099 layers.push_back(layer);
Alec Mouri7c94edb2018-12-03 21:23:26 -08001100
Alec Mouric0aae732021-01-12 13:32:18 -08001101 invokeDraw(settings, layers);
Alec Mouri7c94edb2018-12-03 21:23:26 -08001102}
1103
1104template <typename SourceVariant>
1105void RenderEngineTest::fillBufferWithRoundedCorners() {
1106 fillRedBufferWithRoundedCorners<SourceVariant>();
1107 // Corners should be ignored...
1108 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 0);
1109 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, 0, DEFAULT_DISPLAY_WIDTH, 1), 0, 0, 0, 0);
1110 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT - 1, 1, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
1111 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1,
1112 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1113 0, 0, 0, 0);
1114 // ...And the non-rounded portion should be red.
1115 // Other pixels may be anti-aliased, so let's not check those.
1116 expectBufferColor(Rect(5, 5, DEFAULT_DISPLAY_WIDTH - 5, DEFAULT_DISPLAY_HEIGHT - 5), 255, 0, 0,
1117 255);
1118}
1119
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001120template <typename SourceVariant>
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001121void RenderEngineTest::fillBufferAndBlurBackground() {
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001122 auto blurRadius = 50;
1123 auto center = DEFAULT_DISPLAY_WIDTH / 2;
1124
1125 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001126 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001127 settings.physicalDisplay = fullscreenRect();
1128 settings.clip = fullscreenRect();
1129
Sally Qi59a9f502021-10-12 18:53:23 +00001130 std::vector<renderengine::LayerSettings> layers;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001131
1132 renderengine::LayerSettings backgroundLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001133 backgroundLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001134 backgroundLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1135 SourceVariant::fillColor(backgroundLayer, 0.0f, 1.0f, 0.0f, this);
1136 backgroundLayer.alpha = 1.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001137 layers.emplace_back(backgroundLayer);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001138
1139 renderengine::LayerSettings leftLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001140 leftLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001141 leftLayer.geometry.boundaries =
1142 Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT).toFloatRect();
1143 SourceVariant::fillColor(leftLayer, 1.0f, 0.0f, 0.0f, this);
1144 leftLayer.alpha = 1.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001145 layers.emplace_back(leftLayer);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001146
1147 renderengine::LayerSettings blurLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001148 blurLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001149 blurLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1150 blurLayer.backgroundBlurRadius = blurRadius;
Derek Sollenbergerecb21462021-01-29 16:53:49 -05001151 SourceVariant::fillColor(blurLayer, 0.0f, 0.0f, 1.0f, this);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001152 blurLayer.alpha = 0;
Sally Qi59a9f502021-10-12 18:53:23 +00001153 layers.emplace_back(blurLayer);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001154
Alec Mouric0aae732021-01-12 13:32:18 -08001155 invokeDraw(settings, layers);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001156
Derek Sollenbergerecb21462021-01-29 16:53:49 -05001157 // solid color
1158 expectBufferColor(Rect(0, 0, 1, 1), 255, 0, 0, 255, 0 /* tolerance */);
1159
Derek Sollenbergerb3998372021-02-16 15:16:56 -05001160 if (mRE->supportsBackgroundBlur()) {
1161 // blurred color (downsampling should result in the center color being close to 128)
1162 expectBufferColor(Rect(center - 1, center - 5, center + 1, center + 5), 128, 128, 0, 255,
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001163 50 /* tolerance */);
Derek Sollenbergerb3998372021-02-16 15:16:56 -05001164 }
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001165}
1166
1167template <typename SourceVariant>
Alec Mourie8489fd2021-04-29 16:08:56 -07001168void RenderEngineTest::fillSmallLayerAndBlurBackground() {
1169 auto blurRadius = 50;
1170 renderengine::DisplaySettings settings;
1171 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1172 settings.physicalDisplay = fullscreenRect();
1173 settings.clip = fullscreenRect();
1174
Sally Qi59a9f502021-10-12 18:53:23 +00001175 std::vector<renderengine::LayerSettings> layers;
Alec Mourie8489fd2021-04-29 16:08:56 -07001176
1177 renderengine::LayerSettings backgroundLayer;
1178 backgroundLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1179 backgroundLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1180 SourceVariant::fillColor(backgroundLayer, 1.0f, 0.0f, 0.0f, this);
1181 backgroundLayer.alpha = 1.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001182 layers.push_back(backgroundLayer);
Alec Mourie8489fd2021-04-29 16:08:56 -07001183
1184 renderengine::LayerSettings blurLayer;
1185 blurLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1186 blurLayer.geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f);
1187 blurLayer.backgroundBlurRadius = blurRadius;
1188 SourceVariant::fillColor(blurLayer, 0.0f, 0.0f, 1.0f, this);
1189 blurLayer.alpha = 0;
Sally Qi59a9f502021-10-12 18:53:23 +00001190 layers.push_back(blurLayer);
Alec Mourie8489fd2021-04-29 16:08:56 -07001191
1192 invokeDraw(settings, layers);
1193
1194 // Give a generous tolerance - the blur rectangle is very small and this test is
1195 // mainly concerned with ensuring that there's no device failure.
1196 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT), 255, 0, 0, 255,
1197 40 /* tolerance */);
1198}
1199
1200template <typename SourceVariant>
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001201void RenderEngineTest::overlayCorners() {
1202 renderengine::DisplaySettings settings;
1203 settings.physicalDisplay = fullscreenRect();
1204 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001205 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001206
Sally Qi59a9f502021-10-12 18:53:23 +00001207 std::vector<renderengine::LayerSettings> layersFirst;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001208
1209 renderengine::LayerSettings layerOne;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001210 layerOne.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001211 layerOne.geometry.boundaries =
1212 FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH / 3.0, DEFAULT_DISPLAY_HEIGHT / 3.0);
1213 SourceVariant::fillColor(layerOne, 1.0f, 0.0f, 0.0f, this);
1214 layerOne.alpha = 0.2;
1215
Sally Qi59a9f502021-10-12 18:53:23 +00001216 layersFirst.push_back(layerOne);
Alec Mouric0aae732021-01-12 13:32:18 -08001217 invokeDraw(settings, layersFirst);
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001218 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3), 51, 0, 0, 51);
1219 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3 + 1, DEFAULT_DISPLAY_HEIGHT / 3 + 1,
1220 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1221 0, 0, 0, 0);
1222
Sally Qi59a9f502021-10-12 18:53:23 +00001223 std::vector<renderengine::LayerSettings> layersSecond;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001224 renderengine::LayerSettings layerTwo;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001225 layerTwo.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001226 layerTwo.geometry.boundaries =
1227 FloatRect(DEFAULT_DISPLAY_WIDTH / 3.0, DEFAULT_DISPLAY_HEIGHT / 3.0,
1228 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT);
1229 SourceVariant::fillColor(layerTwo, 0.0f, 1.0f, 0.0f, this);
1230 layerTwo.alpha = 1.0f;
1231
Sally Qi59a9f502021-10-12 18:53:23 +00001232 layersSecond.push_back(layerTwo);
Alec Mouric0aae732021-01-12 13:32:18 -08001233 invokeDraw(settings, layersSecond);
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001234
1235 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3), 0, 0, 0, 0);
1236 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3 + 1, DEFAULT_DISPLAY_HEIGHT / 3 + 1,
1237 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1238 0, 255, 0, 255);
1239}
1240
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001241void RenderEngineTest::fillRedBufferTextureTransform() {
1242 renderengine::DisplaySettings settings;
1243 settings.physicalDisplay = fullscreenRect();
1244 settings.clip = Rect(1, 1);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001245 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001246
Sally Qi59a9f502021-10-12 18:53:23 +00001247 std::vector<renderengine::LayerSettings> layers;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001248
1249 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001250 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001251 // Here will allocate a checker board texture, but transform texture
1252 // coordinates so that only the upper left is applied.
Alec Mouria90a5702021-04-16 16:36:21 +00001253 const auto buf = allocateSourceBuffer(2, 2);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001254 uint32_t texName;
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001255 RenderEngineTest::mRE->genTextures(1, &texName);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001256 this->mTexNames.push_back(texName);
1257
1258 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00001259 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1260 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001261 // Red top left, Green top right, Blue bottom left, Black bottom right
1262 pixels[0] = 255;
1263 pixels[1] = 0;
1264 pixels[2] = 0;
1265 pixels[3] = 255;
1266 pixels[4] = 0;
1267 pixels[5] = 255;
1268 pixels[6] = 0;
1269 pixels[7] = 255;
1270 pixels[8] = 0;
1271 pixels[9] = 0;
1272 pixels[10] = 255;
1273 pixels[11] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00001274 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001275
1276 layer.source.buffer.buffer = buf;
1277 layer.source.buffer.textureName = texName;
1278 // Transform coordinates to only be inside the red quadrant.
Alec Mouri4049b532021-10-15 20:59:33 -07001279 layer.source.buffer.textureTransform = mat4::scale(vec4(0.2f, 0.2f, 1.f, 1.f));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001280 layer.alpha = 1.0f;
1281 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1282
Sally Qi59a9f502021-10-12 18:53:23 +00001283 layers.push_back(layer);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001284
Alec Mouric0aae732021-01-12 13:32:18 -08001285 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001286}
1287
1288void RenderEngineTest::fillBufferTextureTransform() {
1289 fillRedBufferTextureTransform();
1290 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
1291}
1292
1293void RenderEngineTest::fillRedBufferWithPremultiplyAlpha() {
1294 renderengine::DisplaySettings settings;
1295 settings.physicalDisplay = fullscreenRect();
1296 // Here logical space is 1x1
1297 settings.clip = Rect(1, 1);
1298
Sally Qi59a9f502021-10-12 18:53:23 +00001299 std::vector<renderengine::LayerSettings> layers;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001300
1301 renderengine::LayerSettings layer;
Alec Mouria90a5702021-04-16 16:36:21 +00001302 const auto buf = allocateSourceBuffer(1, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001303 uint32_t texName;
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001304 RenderEngineTest::mRE->genTextures(1, &texName);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001305 this->mTexNames.push_back(texName);
1306
1307 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00001308 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1309 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001310 pixels[0] = 255;
1311 pixels[1] = 0;
1312 pixels[2] = 0;
1313 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00001314 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001315
1316 layer.source.buffer.buffer = buf;
1317 layer.source.buffer.textureName = texName;
1318 layer.source.buffer.usePremultipliedAlpha = true;
1319 layer.alpha = 0.5f;
1320 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1321
Sally Qi59a9f502021-10-12 18:53:23 +00001322 layers.push_back(layer);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001323
Alec Mouric0aae732021-01-12 13:32:18 -08001324 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001325}
1326
1327void RenderEngineTest::fillBufferWithPremultiplyAlpha() {
1328 fillRedBufferWithPremultiplyAlpha();
1329 expectBufferColor(fullscreenRect(), 128, 0, 0, 128);
1330}
1331
1332void RenderEngineTest::fillRedBufferWithoutPremultiplyAlpha() {
1333 renderengine::DisplaySettings settings;
1334 settings.physicalDisplay = fullscreenRect();
1335 // Here logical space is 1x1
1336 settings.clip = Rect(1, 1);
1337
Sally Qi59a9f502021-10-12 18:53:23 +00001338 std::vector<renderengine::LayerSettings> layers;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001339
1340 renderengine::LayerSettings layer;
Alec Mouria90a5702021-04-16 16:36:21 +00001341 const auto buf = allocateSourceBuffer(1, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001342 uint32_t texName;
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001343 RenderEngineTest::mRE->genTextures(1, &texName);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001344 this->mTexNames.push_back(texName);
1345
1346 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00001347 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1348 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001349 pixels[0] = 255;
1350 pixels[1] = 0;
1351 pixels[2] = 0;
1352 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00001353 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001354
1355 layer.source.buffer.buffer = buf;
1356 layer.source.buffer.textureName = texName;
1357 layer.source.buffer.usePremultipliedAlpha = false;
1358 layer.alpha = 0.5f;
1359 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1360
Sally Qi59a9f502021-10-12 18:53:23 +00001361 layers.push_back(layer);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001362
Alec Mouric0aae732021-01-12 13:32:18 -08001363 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001364}
1365
1366void RenderEngineTest::fillBufferWithoutPremultiplyAlpha() {
1367 fillRedBufferWithoutPremultiplyAlpha();
wukui16f3c0bb2020-08-05 20:35:29 +08001368 expectBufferColor(fullscreenRect(), 128, 0, 0, 128, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001369}
1370
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001371template <typename SourceVariant>
1372void RenderEngineTest::drawShadow(const renderengine::LayerSettings& castingLayer,
1373 const renderengine::ShadowSettings& shadow,
1374 const ubyte4& casterColor, const ubyte4& backgroundColor) {
1375 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001376 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001377 settings.physicalDisplay = fullscreenRect();
1378 settings.clip = fullscreenRect();
1379
Sally Qi59a9f502021-10-12 18:53:23 +00001380 std::vector<renderengine::LayerSettings> layers;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001381
1382 // add background layer
1383 renderengine::LayerSettings bgLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001384 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001385 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1386 ColorSourceVariant::fillColor(bgLayer, backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1387 backgroundColor.b / 255.0f, this);
1388 bgLayer.alpha = backgroundColor.a / 255.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001389 layers.push_back(bgLayer);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001390
1391 // add shadow layer
1392 renderengine::LayerSettings shadowLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001393 shadowLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001394 shadowLayer.geometry.boundaries = castingLayer.geometry.boundaries;
1395 shadowLayer.alpha = castingLayer.alpha;
1396 shadowLayer.shadow = shadow;
Sally Qi59a9f502021-10-12 18:53:23 +00001397 layers.push_back(shadowLayer);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001398
1399 // add layer casting the shadow
1400 renderengine::LayerSettings layer = castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001401 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001402 SourceVariant::fillColor(layer, casterColor.r / 255.0f, casterColor.g / 255.0f,
1403 casterColor.b / 255.0f, this);
Sally Qi59a9f502021-10-12 18:53:23 +00001404 layers.push_back(layer);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001405
Alec Mouric0aae732021-01-12 13:32:18 -08001406 invokeDraw(settings, layers);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001407}
1408
Alec Mouribd17b3b2020-12-17 11:08:30 -08001409void RenderEngineTest::drawShadowWithoutCaster(const FloatRect& castingBounds,
1410 const renderengine::ShadowSettings& shadow,
1411 const ubyte4& backgroundColor) {
1412 renderengine::DisplaySettings settings;
1413 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1414 settings.physicalDisplay = fullscreenRect();
1415 settings.clip = fullscreenRect();
1416
Sally Qi59a9f502021-10-12 18:53:23 +00001417 std::vector<renderengine::LayerSettings> layers;
Alec Mouribd17b3b2020-12-17 11:08:30 -08001418
1419 // add background layer
1420 renderengine::LayerSettings bgLayer;
1421 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1422 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1423 ColorSourceVariant::fillColor(bgLayer, backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1424 backgroundColor.b / 255.0f, this);
1425 bgLayer.alpha = backgroundColor.a / 255.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001426 layers.push_back(bgLayer);
Alec Mouribd17b3b2020-12-17 11:08:30 -08001427
1428 // add shadow layer
1429 renderengine::LayerSettings shadowLayer;
1430 shadowLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1431 shadowLayer.geometry.boundaries = castingBounds;
Derek Sollenbergerc31985e2021-05-18 16:38:17 -04001432 shadowLayer.skipContentDraw = true;
Alec Mouribd17b3b2020-12-17 11:08:30 -08001433 shadowLayer.alpha = 1.0f;
1434 ColorSourceVariant::fillColor(shadowLayer, 0, 0, 0, this);
1435 shadowLayer.shadow = shadow;
Sally Qi59a9f502021-10-12 18:53:23 +00001436 layers.push_back(shadowLayer);
Alec Mouribd17b3b2020-12-17 11:08:30 -08001437
Alec Mouric0aae732021-01-12 13:32:18 -08001438 invokeDraw(settings, layers);
Alec Mouribd17b3b2020-12-17 11:08:30 -08001439}
1440
Alec Mouri5a493722022-01-26 16:43:02 -08001441void RenderEngineTest::tonemap(ui::Dataspace sourceDataspace, std::function<vec3(vec3)> eotf,
1442 std::function<vec3(vec3, float)> scaleOotf) {
1443 constexpr int32_t kGreyLevels = 256;
1444
1445 const auto rect = Rect(0, 0, kGreyLevels, 1);
1446
1447 constexpr float kMaxLuminance = 750.f;
1448 constexpr float kCurrentLuminanceNits = 500.f;
1449 const renderengine::DisplaySettings display{
1450 .physicalDisplay = rect,
1451 .clip = rect,
1452 .maxLuminance = kMaxLuminance,
1453 .currentLuminanceNits = kCurrentLuminanceNits,
1454 .outputDataspace = ui::Dataspace::DISPLAY_P3,
1455 };
1456
1457 auto buf = 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 "input"),
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, buf->getBuffer()->initCheck());
1470 {
1471 uint8_t* pixels;
1472 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1473 reinterpret_cast<void**>(&pixels));
1474
1475 uint8_t color = 0;
1476 for (int32_t j = 0; j < buf->getBuffer()->getHeight(); j++) {
1477 uint8_t* dest = pixels + (buf->getBuffer()->getStride() * j * 4);
1478 for (int32_t i = 0; i < buf->getBuffer()->getWidth(); i++) {
1479 dest[0] = color;
1480 dest[1] = color;
1481 dest[2] = color;
1482 dest[3] = 255;
1483 color++;
1484 dest += 4;
1485 }
1486 }
1487 buf->getBuffer()->unlock();
1488 }
1489
1490 mBuffer = std::make_shared<
1491 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07001492 ExternalTexture>(sp<GraphicBuffer>::make(kGreyLevels, 1,
1493 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1494 GRALLOC_USAGE_SW_READ_OFTEN |
1495 GRALLOC_USAGE_SW_WRITE_OFTEN |
1496 GRALLOC_USAGE_HW_RENDER |
1497 GRALLOC_USAGE_HW_TEXTURE,
1498 "output"),
Alec Mouri5a493722022-01-26 16:43:02 -08001499 *mRE,
1500 renderengine::impl::ExternalTexture::Usage::READABLE |
1501 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
1502 ASSERT_EQ(0, mBuffer->getBuffer()->initCheck());
1503
1504 const renderengine::LayerSettings layer{.geometry.boundaries = rect.toFloatRect(),
1505 .source =
1506 renderengine::PixelSource{
1507 .buffer =
1508 renderengine::Buffer{
1509 .buffer =
1510 std::move(buf),
1511 .usePremultipliedAlpha =
1512 true,
1513 },
1514 },
1515 .alpha = 1.0f,
1516 .sourceDataspace = sourceDataspace};
1517
1518 std::vector<renderengine::LayerSettings> layers{layer};
1519 invokeDraw(display, layers);
1520
1521 ColorSpace displayP3 = ColorSpace::DisplayP3();
1522 ColorSpace bt2020 = ColorSpace::BT2020();
1523
1524 tonemap::Metadata metadata{.displayMaxLuminance = 750.0f};
1525
1526 auto generator = [=](Point location) {
1527 const double normColor = static_cast<double>(location.x) / (kGreyLevels - 1);
1528 const vec3 rgb = vec3(normColor, normColor, normColor);
1529
1530 const vec3 linearRGB = eotf(rgb);
1531
1532 const vec3 xyz = bt2020.getRGBtoXYZ() * linearRGB;
1533
1534 const vec3 scaledXYZ = scaleOotf(xyz, kCurrentLuminanceNits);
Alec Mouri196b0f22022-03-04 22:13:48 +00001535 const auto gains =
Alec Mouri5a493722022-01-26 16:43:02 -08001536 tonemap::getToneMapper()
1537 ->lookupTonemapGain(static_cast<aidl::android::hardware::graphics::common::
1538 Dataspace>(sourceDataspace),
1539 static_cast<aidl::android::hardware::graphics::common::
1540 Dataspace>(
1541 ui::Dataspace::DISPLAY_P3),
Alec Mouri196b0f22022-03-04 22:13:48 +00001542 {tonemap::
1543 Color{.linearRGB =
1544 scaleOotf(linearRGB,
1545 kCurrentLuminanceNits),
1546 .xyz = scaledXYZ}},
Alec Mouri5a493722022-01-26 16:43:02 -08001547 metadata);
Alec Mouri196b0f22022-03-04 22:13:48 +00001548 EXPECT_EQ(1, gains.size());
1549 const double gain = gains.front();
Alec Mouri5a493722022-01-26 16:43:02 -08001550 const vec3 normalizedXYZ = scaledXYZ * gain / metadata.displayMaxLuminance;
1551
1552 const vec3 targetRGB = OETF_sRGB(displayP3.getXYZtoRGB() * normalizedXYZ) * 255;
1553 return ubyte4(static_cast<uint8_t>(targetRGB.r), static_cast<uint8_t>(targetRGB.g),
1554 static_cast<uint8_t>(targetRGB.b), 255);
1555 };
1556
1557 expectBufferColor(Rect(kGreyLevels, 1), generator, 2);
1558}
1559
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001560INSTANTIATE_TEST_SUITE_P(PerRenderEngineType, RenderEngineTest,
Alec Mouric16974e2022-09-13 17:35:48 +00001561 testing::Values(std::make_shared<SkiaGLESRenderEngineFactory>(),
Ian Elliott1f0911e2022-09-09 16:31:47 -06001562 std::make_shared<SkiaGLESCMRenderEngineFactory>(),
1563 std::make_shared<SkiaVkRenderEngineFactory>(),
1564 std::make_shared<SkiaVkCMRenderEngineFactory>()));
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001565
1566TEST_P(RenderEngineTest, drawLayers_noLayersToDraw) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001567 if (!GetParam()->typeSupported()) {
1568 GTEST_SKIP();
1569 }
Alec Mouric0aae732021-01-12 13:32:18 -08001570 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001571 drawEmptyLayers();
1572}
1573
Sally Qi1fed86e2022-06-23 15:33:52 -07001574TEST_P(RenderEngineTest, drawLayers_fillRedBufferAndEmptyBuffer) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001575 if (!GetParam()->typeSupported()) {
1576 GTEST_SKIP();
1577 }
Sally Qi1fed86e2022-06-23 15:33:52 -07001578 initializeRenderEngine();
1579 renderengine::DisplaySettings settings;
1580 settings.physicalDisplay = fullscreenRect();
1581 settings.clip = fullscreenRect();
1582 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1583
1584 // add a red layer
1585 renderengine::LayerSettings layerOne{
1586 .geometry.boundaries = fullscreenRect().toFloatRect(),
1587 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
1588 .alpha = 1.f,
1589 };
1590
1591 std::vector<renderengine::LayerSettings> layersFirst{layerOne};
1592 invokeDraw(settings, layersFirst);
1593 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
1594
1595 // re-draw with an empty layer above it, and we get a transparent black one
1596 std::vector<renderengine::LayerSettings> layersSecond;
1597 invokeDraw(settings, layersSecond);
1598 expectBufferColor(fullscreenRect(), 0, 0, 0, 0);
1599}
1600
Ana Krulec07b98df2021-01-07 14:38:40 -08001601TEST_P(RenderEngineTest, drawLayers_withoutBuffers_withColorTransform) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001602 if (!GetParam()->typeSupported()) {
1603 GTEST_SKIP();
1604 }
Alec Mouria90a5702021-04-16 16:36:21 +00001605 initializeRenderEngine();
Ana Krulec07b98df2021-01-07 14:38:40 -08001606
1607 renderengine::DisplaySettings settings;
1608 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1609 settings.physicalDisplay = fullscreenRect();
1610 settings.clip = fullscreenRect();
1611
1612 // 255, 255, 255, 255 is full opaque white.
Alec Mouri4049b532021-10-15 20:59:33 -07001613 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
1614 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Ana Krulec07b98df2021-01-07 14:38:40 -08001615 // Create layer with given color.
1616 renderengine::LayerSettings bgLayer;
1617 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1618 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1619 bgLayer.source.solidColor = half3(backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1620 backgroundColor.b / 255.0f);
1621 bgLayer.alpha = backgroundColor.a / 255.0f;
1622 // Transform the red color.
1623 bgLayer.colorTransform = mat4(-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
1624
Sally Qi59a9f502021-10-12 18:53:23 +00001625 std::vector<renderengine::LayerSettings> layers;
1626 layers.push_back(bgLayer);
Ana Krulec07b98df2021-01-07 14:38:40 -08001627
Alec Mouric0aae732021-01-12 13:32:18 -08001628 invokeDraw(settings, layers);
Ana Krulec07b98df2021-01-07 14:38:40 -08001629
1630 // Expect to see full opaque pixel (with inverted red from the transform).
Alec Mouric0aae732021-01-12 13:32:18 -08001631 expectBufferColor(Rect(0, 0, 10, 10), 0.f, backgroundColor.g, backgroundColor.b,
Ana Krulec07b98df2021-01-07 14:38:40 -08001632 backgroundColor.a);
1633}
1634
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001635TEST_P(RenderEngineTest, drawLayers_nullOutputBuffer) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001636 if (!GetParam()->typeSupported()) {
1637 GTEST_SKIP();
1638 }
Alec Mouric0aae732021-01-12 13:32:18 -08001639 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001640
Alec Mourid43ccab2019-03-13 12:23:45 -07001641 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001642 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Sally Qi59a9f502021-10-12 18:53:23 +00001643 std::vector<renderengine::LayerSettings> layers;
Alec Mourid43ccab2019-03-13 12:23:45 -07001644 renderengine::LayerSettings layer;
1645 layer.geometry.boundaries = fullscreenRect().toFloatRect();
1646 BufferSourceVariant<ForceOpaqueBufferVariant>::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
Sally Qi59a9f502021-10-12 18:53:23 +00001647 layers.push_back(layer);
Patrick Williams2e9748f2022-08-09 22:48:18 +00001648 ftl::Future<FenceResult> future =
Sally Qi4cabdd02021-08-05 16:45:57 -07001649 mRE->drawLayers(settings, layers, nullptr, true, base::unique_fd());
Alec Mourid43ccab2019-03-13 12:23:45 -07001650
Patrick Williams2e9748f2022-08-09 22:48:18 +00001651 ASSERT_TRUE(future.valid());
1652 auto result = future.get();
1653 ASSERT_FALSE(result.ok());
1654 ASSERT_EQ(BAD_VALUE, result.error());
Alec Mourid43ccab2019-03-13 12:23:45 -07001655}
1656
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001657TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001658 if (!GetParam()->typeSupported()) {
1659 GTEST_SKIP();
1660 }
Alec Mouric0aae732021-01-12 13:32:18 -08001661 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001662 fillRedBuffer<ColorSourceVariant>();
1663}
1664
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001665TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001666 if (!GetParam()->typeSupported()) {
1667 GTEST_SKIP();
1668 }
Alec Mouric0aae732021-01-12 13:32:18 -08001669 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001670 fillGreenBuffer<ColorSourceVariant>();
1671}
1672
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001673TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001674 if (!GetParam()->typeSupported()) {
1675 GTEST_SKIP();
1676 }
Alec Mouric0aae732021-01-12 13:32:18 -08001677 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001678 fillBlueBuffer<ColorSourceVariant>();
1679}
1680
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001681TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001682 if (!GetParam()->typeSupported()) {
1683 GTEST_SKIP();
1684 }
Alec Mouric0aae732021-01-12 13:32:18 -08001685 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001686 fillRedTransparentBuffer<ColorSourceVariant>();
1687}
1688
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001689TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001690 if (!GetParam()->typeSupported()) {
1691 GTEST_SKIP();
1692 }
Alec Mouric0aae732021-01-12 13:32:18 -08001693 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001694 fillBufferPhysicalOffset<ColorSourceVariant>();
1695}
1696
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001697TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001698 if (!GetParam()->typeSupported()) {
1699 GTEST_SKIP();
1700 }
Alec Mouric0aae732021-01-12 13:32:18 -08001701 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001702 fillBufferCheckersRotate0<ColorSourceVariant>();
1703}
1704
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001705TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001706 if (!GetParam()->typeSupported()) {
1707 GTEST_SKIP();
1708 }
Alec Mouric0aae732021-01-12 13:32:18 -08001709 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001710 fillBufferCheckersRotate90<ColorSourceVariant>();
1711}
1712
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001713TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001714 if (!GetParam()->typeSupported()) {
1715 GTEST_SKIP();
1716 }
Alec Mouric0aae732021-01-12 13:32:18 -08001717 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001718 fillBufferCheckersRotate180<ColorSourceVariant>();
1719}
1720
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001721TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001722 if (!GetParam()->typeSupported()) {
1723 GTEST_SKIP();
1724 }
Alec Mouric0aae732021-01-12 13:32:18 -08001725 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001726 fillBufferCheckersRotate270<ColorSourceVariant>();
1727}
1728
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001729TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001730 if (!GetParam()->typeSupported()) {
1731 GTEST_SKIP();
1732 }
Alec Mouric0aae732021-01-12 13:32:18 -08001733 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001734 fillBufferLayerTransform<ColorSourceVariant>();
1735}
1736
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001737TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001738 if (!GetParam()->typeSupported()) {
1739 GTEST_SKIP();
1740 }
Alec Mouric0aae732021-01-12 13:32:18 -08001741 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08001742 fillBufferColorTransform<ColorSourceVariant>();
1743}
1744
Sally Qi2019fd22021-11-22 10:19:04 -08001745TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_sourceDataspace) {
1746 const auto& renderEngineFactory = GetParam();
1747 // skip for non color management
Ian Elliott1f0911e2022-09-09 16:31:47 -06001748 if (!renderEngineFactory->typeSupported() || !renderEngineFactory->useColorManagement()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001749 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001750 }
1751
1752 initializeRenderEngine();
1753 fillBufferColorTransformAndSourceDataspace<ColorSourceVariant>();
1754}
1755
1756TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_outputDataspace) {
1757 const auto& renderEngineFactory = GetParam();
1758 // skip for non color management
Ian Elliott1f0911e2022-09-09 16:31:47 -06001759 if (!renderEngineFactory->typeSupported() || !renderEngineFactory->useColorManagement()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001760 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001761 }
1762
1763 initializeRenderEngine();
1764 fillBufferColorTransformAndOutputDataspace<ColorSourceVariant>();
1765}
1766
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001767TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001768 if (!GetParam()->typeSupported()) {
1769 GTEST_SKIP();
1770 }
Alec Mouric0aae732021-01-12 13:32:18 -08001771 initializeRenderEngine();
Alec Mouri7c94edb2018-12-03 21:23:26 -08001772 fillBufferWithRoundedCorners<ColorSourceVariant>();
1773}
1774
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001775TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001776 if (!GetParam()->typeSupported()) {
1777 GTEST_SKIP();
1778 }
Alec Mouric0aae732021-01-12 13:32:18 -08001779 initializeRenderEngine();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001780 fillBufferColorTransformZeroLayerAlpha<ColorSourceVariant>();
1781}
1782
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001783TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001784 if (!GetParam()->typeSupported()) {
1785 GTEST_SKIP();
1786 }
Alec Mouric0aae732021-01-12 13:32:18 -08001787 initializeRenderEngine();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001788 fillBufferAndBlurBackground<ColorSourceVariant>();
1789}
1790
Alec Mourie8489fd2021-04-29 16:08:56 -07001791TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001792 if (!GetParam()->typeSupported()) {
1793 GTEST_SKIP();
1794 }
Alec Mourie8489fd2021-04-29 16:08:56 -07001795 initializeRenderEngine();
1796 fillSmallLayerAndBlurBackground<ColorSourceVariant>();
1797}
1798
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001799TEST_P(RenderEngineTest, drawLayers_overlayCorners_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001800 if (!GetParam()->typeSupported()) {
1801 GTEST_SKIP();
1802 }
Alec Mouric0aae732021-01-12 13:32:18 -08001803 initializeRenderEngine();
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001804 overlayCorners<ColorSourceVariant>();
1805}
1806
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001807TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001808 if (!GetParam()->typeSupported()) {
1809 GTEST_SKIP();
1810 }
Alec Mouric0aae732021-01-12 13:32:18 -08001811 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001812 fillRedBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1813}
1814
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001815TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001816 if (!GetParam()->typeSupported()) {
1817 GTEST_SKIP();
1818 }
Alec Mouric0aae732021-01-12 13:32:18 -08001819 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001820 fillGreenBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1821}
1822
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001823TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001824 if (!GetParam()->typeSupported()) {
1825 GTEST_SKIP();
1826 }
Alec Mouric0aae732021-01-12 13:32:18 -08001827 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001828 fillBlueBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1829}
1830
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001831TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001832 if (!GetParam()->typeSupported()) {
1833 GTEST_SKIP();
1834 }
Alec Mouric0aae732021-01-12 13:32:18 -08001835 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001836 fillRedTransparentBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1837}
1838
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001839TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001840 if (!GetParam()->typeSupported()) {
1841 GTEST_SKIP();
1842 }
Alec Mouric0aae732021-01-12 13:32:18 -08001843 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001844 fillBufferPhysicalOffset<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1845}
1846
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001847TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001848 if (!GetParam()->typeSupported()) {
1849 GTEST_SKIP();
1850 }
Alec Mouric0aae732021-01-12 13:32:18 -08001851 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001852 fillBufferCheckersRotate0<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1853}
1854
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001855TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001856 if (!GetParam()->typeSupported()) {
1857 GTEST_SKIP();
1858 }
Alec Mouric0aae732021-01-12 13:32:18 -08001859 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001860 fillBufferCheckersRotate90<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1861}
1862
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001863TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001864 if (!GetParam()->typeSupported()) {
1865 GTEST_SKIP();
1866 }
Alec Mouric0aae732021-01-12 13:32:18 -08001867 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001868 fillBufferCheckersRotate180<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1869}
1870
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001871TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001872 if (!GetParam()->typeSupported()) {
1873 GTEST_SKIP();
1874 }
Alec Mouric0aae732021-01-12 13:32:18 -08001875 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001876 fillBufferCheckersRotate270<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1877}
1878
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001879TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001880 if (!GetParam()->typeSupported()) {
1881 GTEST_SKIP();
1882 }
Alec Mouric0aae732021-01-12 13:32:18 -08001883 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001884 fillBufferLayerTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1885}
1886
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001887TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001888 if (!GetParam()->typeSupported()) {
1889 GTEST_SKIP();
1890 }
Alec Mouric0aae732021-01-12 13:32:18 -08001891 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08001892 fillBufferColorTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1893}
1894
Sally Qi2019fd22021-11-22 10:19:04 -08001895TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndSourceDataspace_opaqueBufferSource) {
1896 const auto& renderEngineFactory = GetParam();
1897 // skip for non color management
Ian Elliott1f0911e2022-09-09 16:31:47 -06001898 if (!renderEngineFactory->typeSupported() || !renderEngineFactory->useColorManagement()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001899 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001900 }
1901
1902 initializeRenderEngine();
1903 fillBufferColorTransformAndSourceDataspace<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1904}
1905
1906TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndOutputDataspace_opaqueBufferSource) {
1907 const auto& renderEngineFactory = GetParam();
1908 // skip for non color management
Ian Elliott1f0911e2022-09-09 16:31:47 -06001909 if (!renderEngineFactory->typeSupported() || !renderEngineFactory->useColorManagement()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001910 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001911 }
1912
1913 initializeRenderEngine();
1914 fillBufferColorTransformAndOutputDataspace<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1915}
1916
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001917TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001918 if (!GetParam()->typeSupported()) {
1919 GTEST_SKIP();
1920 }
Alec Mouric0aae732021-01-12 13:32:18 -08001921 initializeRenderEngine();
Alec Mouri7c94edb2018-12-03 21:23:26 -08001922 fillBufferWithRoundedCorners<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1923}
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001924
Alec Mouric0aae732021-01-12 13:32:18 -08001925TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001926 if (!GetParam()->typeSupported()) {
1927 GTEST_SKIP();
1928 }
Alec Mouric0aae732021-01-12 13:32:18 -08001929 initializeRenderEngine();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001930 fillBufferColorTransformZeroLayerAlpha<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1931}
Alec Mouri7c94edb2018-12-03 21:23:26 -08001932
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001933TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001934 if (!GetParam()->typeSupported()) {
1935 GTEST_SKIP();
1936 }
Alec Mouric0aae732021-01-12 13:32:18 -08001937 initializeRenderEngine();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001938 fillBufferAndBlurBackground<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1939}
1940
Alec Mourie8489fd2021-04-29 16:08:56 -07001941TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001942 if (!GetParam()->typeSupported()) {
1943 GTEST_SKIP();
1944 }
Alec Mourie8489fd2021-04-29 16:08:56 -07001945 initializeRenderEngine();
1946 fillSmallLayerAndBlurBackground<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1947}
1948
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001949TEST_P(RenderEngineTest, drawLayers_overlayCorners_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001950 if (!GetParam()->typeSupported()) {
1951 GTEST_SKIP();
1952 }
Alec Mouric0aae732021-01-12 13:32:18 -08001953 initializeRenderEngine();
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001954 overlayCorners<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1955}
1956
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001957TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001958 if (!GetParam()->typeSupported()) {
1959 GTEST_SKIP();
1960 }
Alec Mouric0aae732021-01-12 13:32:18 -08001961 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001962 fillRedBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1963}
1964
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001965TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001966 if (!GetParam()->typeSupported()) {
1967 GTEST_SKIP();
1968 }
Alec Mouric0aae732021-01-12 13:32:18 -08001969 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001970 fillGreenBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1971}
1972
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001973TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001974 if (!GetParam()->typeSupported()) {
1975 GTEST_SKIP();
1976 }
Alec Mouric0aae732021-01-12 13:32:18 -08001977 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001978 fillBlueBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1979}
1980
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001981TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001982 if (!GetParam()->typeSupported()) {
1983 GTEST_SKIP();
1984 }
Alec Mouric0aae732021-01-12 13:32:18 -08001985 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001986 fillRedTransparentBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1987}
1988
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001989TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001990 if (!GetParam()->typeSupported()) {
1991 GTEST_SKIP();
1992 }
Alec Mouric0aae732021-01-12 13:32:18 -08001993 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001994 fillBufferPhysicalOffset<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1995}
1996
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001997TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001998 if (!GetParam()->typeSupported()) {
1999 GTEST_SKIP();
2000 }
Alec Mouric0aae732021-01-12 13:32:18 -08002001 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002002 fillBufferCheckersRotate0<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2003}
2004
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002005TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002006 if (!GetParam()->typeSupported()) {
2007 GTEST_SKIP();
2008 }
Alec Mouric0aae732021-01-12 13:32:18 -08002009 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002010 fillBufferCheckersRotate90<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2011}
2012
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002013TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002014 if (!GetParam()->typeSupported()) {
2015 GTEST_SKIP();
2016 }
Alec Mouric0aae732021-01-12 13:32:18 -08002017 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002018 fillBufferCheckersRotate180<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2019}
2020
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002021TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002022 if (!GetParam()->typeSupported()) {
2023 GTEST_SKIP();
2024 }
Alec Mouric0aae732021-01-12 13:32:18 -08002025 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002026 fillBufferCheckersRotate270<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2027}
2028
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002029TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002030 if (!GetParam()->typeSupported()) {
2031 GTEST_SKIP();
2032 }
Alec Mouric0aae732021-01-12 13:32:18 -08002033 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002034 fillBufferLayerTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2035}
2036
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002037TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002038 if (!GetParam()->typeSupported()) {
2039 GTEST_SKIP();
2040 }
Alec Mouric0aae732021-01-12 13:32:18 -08002041 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08002042 fillBufferColorTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2043}
2044
Sally Qi2019fd22021-11-22 10:19:04 -08002045TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndSourceDataspace_bufferSource) {
2046 const auto& renderEngineFactory = GetParam();
2047 // skip for non color management
Ian Elliott1f0911e2022-09-09 16:31:47 -06002048 if (!renderEngineFactory->typeSupported() || !renderEngineFactory->useColorManagement()) {
Alec Mouric16974e2022-09-13 17:35:48 +00002049 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08002050 }
2051
2052 initializeRenderEngine();
2053 fillBufferColorTransformAndSourceDataspace<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2054}
2055
2056TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndOutputDataspace_bufferSource) {
2057 const auto& renderEngineFactory = GetParam();
2058 // skip for non color management
Ian Elliott1f0911e2022-09-09 16:31:47 -06002059 if (!renderEngineFactory->typeSupported() || !renderEngineFactory->useColorManagement()) {
Alec Mouric16974e2022-09-13 17:35:48 +00002060 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08002061 }
2062
2063 initializeRenderEngine();
2064 fillBufferColorTransformAndOutputDataspace<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2065}
2066
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002067TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002068 if (!GetParam()->typeSupported()) {
2069 GTEST_SKIP();
2070 }
Alec Mouric0aae732021-01-12 13:32:18 -08002071 initializeRenderEngine();
Alec Mouri7c94edb2018-12-03 21:23:26 -08002072 fillBufferWithRoundedCorners<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2073}
2074
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08002075TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002076 if (!GetParam()->typeSupported()) {
2077 GTEST_SKIP();
2078 }
Alec Mouric0aae732021-01-12 13:32:18 -08002079 initializeRenderEngine();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08002080 fillBufferColorTransformZeroLayerAlpha<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2081}
2082
Nathaniel Nifong53494f32021-04-30 14:05:39 -04002083TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002084 if (!GetParam()->typeSupported()) {
2085 GTEST_SKIP();
2086 }
Alec Mouric0aae732021-01-12 13:32:18 -08002087 initializeRenderEngine();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08002088 fillBufferAndBlurBackground<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2089}
2090
Alec Mourie8489fd2021-04-29 16:08:56 -07002091TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002092 if (!GetParam()->typeSupported()) {
2093 GTEST_SKIP();
2094 }
Alec Mourie8489fd2021-04-29 16:08:56 -07002095 initializeRenderEngine();
2096 fillSmallLayerAndBlurBackground<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2097}
2098
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002099TEST_P(RenderEngineTest, drawLayers_overlayCorners_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002100 if (!GetParam()->typeSupported()) {
2101 GTEST_SKIP();
2102 }
Alec Mouric0aae732021-01-12 13:32:18 -08002103 initializeRenderEngine();
Alec Mourie7d1d4a2019-02-05 01:13:46 +00002104 overlayCorners<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2105}
2106
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002107TEST_P(RenderEngineTest, drawLayers_fillBufferTextureTransform) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002108 if (!GetParam()->typeSupported()) {
2109 GTEST_SKIP();
2110 }
Alec Mouric0aae732021-01-12 13:32:18 -08002111 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002112 fillBufferTextureTransform();
2113}
2114
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002115TEST_P(RenderEngineTest, drawLayers_fillBuffer_premultipliesAlpha) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002116 if (!GetParam()->typeSupported()) {
2117 GTEST_SKIP();
2118 }
Alec Mouric0aae732021-01-12 13:32:18 -08002119 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002120 fillBufferWithPremultiplyAlpha();
2121}
2122
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002123TEST_P(RenderEngineTest, drawLayers_fillBuffer_withoutPremultiplyingAlpha) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002124 if (!GetParam()->typeSupported()) {
2125 GTEST_SKIP();
2126 }
Alec Mouric0aae732021-01-12 13:32:18 -08002127 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002128 fillBufferWithoutPremultiplyAlpha();
2129}
2130
Alec Mouribd17b3b2020-12-17 11:08:30 -08002131TEST_P(RenderEngineTest, drawLayers_fillShadow_castsWithoutCasterLayer) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002132 if (!GetParam()->typeSupported()) {
2133 GTEST_SKIP();
2134 }
Alec Mouric0aae732021-01-12 13:32:18 -08002135 initializeRenderEngine();
Alec Mouribd17b3b2020-12-17 11:08:30 -08002136
Alec Mouri4049b532021-10-15 20:59:33 -07002137 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2138 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Alec Mouribd17b3b2020-12-17 11:08:30 -08002139 const float shadowLength = 5.0f;
2140 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2141 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2142 renderengine::ShadowSettings settings =
2143 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2144 false /* casterIsTranslucent */);
2145
2146 drawShadowWithoutCaster(casterBounds.toFloatRect(), settings, backgroundColor);
2147 expectShadowColorWithoutCaster(casterBounds.toFloatRect(), settings, backgroundColor);
2148}
2149
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002150TEST_P(RenderEngineTest, drawLayers_fillShadow_casterLayerMinSize) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002151 if (!GetParam()->typeSupported()) {
2152 GTEST_SKIP();
2153 }
Alec Mouric0aae732021-01-12 13:32:18 -08002154 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002155
Alec Mouri4049b532021-10-15 20:59:33 -07002156 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2157 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2158 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2159 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002160 const float shadowLength = 5.0f;
2161 Rect casterBounds(1, 1);
2162 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2163 renderengine::LayerSettings castingLayer;
2164 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2165 castingLayer.alpha = 1.0f;
2166 renderengine::ShadowSettings settings =
2167 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2168 false /* casterIsTranslucent */);
2169
2170 drawShadow<ColorSourceVariant>(castingLayer, settings, casterColor, backgroundColor);
2171 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2172}
2173
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002174TEST_P(RenderEngineTest, drawLayers_fillShadow_casterColorLayer) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002175 if (!GetParam()->typeSupported()) {
2176 GTEST_SKIP();
2177 }
Alec Mouric0aae732021-01-12 13:32:18 -08002178 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002179
Alec Mouri4049b532021-10-15 20:59:33 -07002180 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2181 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2182 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2183 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002184 const float shadowLength = 5.0f;
2185 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2186 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2187 renderengine::LayerSettings castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002188 castingLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002189 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2190 castingLayer.alpha = 1.0f;
2191 renderengine::ShadowSettings settings =
2192 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2193 false /* casterIsTranslucent */);
2194
2195 drawShadow<ColorSourceVariant>(castingLayer, settings, casterColor, backgroundColor);
2196 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2197}
2198
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002199TEST_P(RenderEngineTest, drawLayers_fillShadow_casterOpaqueBufferLayer) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002200 if (!GetParam()->typeSupported()) {
2201 GTEST_SKIP();
2202 }
Alec Mouric0aae732021-01-12 13:32:18 -08002203 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002204
Alec Mouri4049b532021-10-15 20:59:33 -07002205 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2206 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2207 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2208 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002209 const float shadowLength = 5.0f;
2210 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2211 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2212 renderengine::LayerSettings castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002213 castingLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002214 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2215 castingLayer.alpha = 1.0f;
2216 renderengine::ShadowSettings settings =
2217 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2218 false /* casterIsTranslucent */);
2219
2220 drawShadow<BufferSourceVariant<ForceOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2221 backgroundColor);
2222 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2223}
2224
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002225TEST_P(RenderEngineTest, drawLayers_fillShadow_casterWithRoundedCorner) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002226 if (!GetParam()->typeSupported()) {
2227 GTEST_SKIP();
2228 }
Alec Mouric0aae732021-01-12 13:32:18 -08002229 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002230
Alec Mouri4049b532021-10-15 20:59:33 -07002231 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2232 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2233 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2234 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002235 const float shadowLength = 5.0f;
2236 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2237 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2238 renderengine::LayerSettings castingLayer;
2239 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002240 castingLayer.geometry.roundedCornersRadius = {3.0f, 3.0f};
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002241 castingLayer.geometry.roundedCornersCrop = casterBounds.toFloatRect();
2242 castingLayer.alpha = 1.0f;
2243 renderengine::ShadowSettings settings =
2244 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2245 false /* casterIsTranslucent */);
2246
2247 drawShadow<BufferSourceVariant<ForceOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2248 backgroundColor);
2249 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2250}
2251
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002252TEST_P(RenderEngineTest, drawLayers_fillShadow_translucentCasterWithAlpha) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002253 if (!GetParam()->typeSupported()) {
2254 GTEST_SKIP();
2255 }
Alec Mouric0aae732021-01-12 13:32:18 -08002256 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002257
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002258 const ubyte4 casterColor(255, 0, 0, 255);
2259 const ubyte4 backgroundColor(255, 255, 255, 255);
2260 const float shadowLength = 5.0f;
2261 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2262 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2263 renderengine::LayerSettings castingLayer;
2264 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2265 castingLayer.alpha = 0.5f;
2266 renderengine::ShadowSettings settings =
2267 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2268 true /* casterIsTranslucent */);
2269
2270 drawShadow<BufferSourceVariant<RelaxOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2271 backgroundColor);
2272
2273 // verify only the background since the shadow will draw behind the caster
2274 const float shadowInset = settings.length * -1.0f;
2275 const Rect casterWithShadow =
2276 Rect(casterBounds).inset(shadowInset, shadowInset, shadowInset, shadowInset);
2277 const Region backgroundRegion = Region(fullscreenRect()).subtractSelf(casterWithShadow);
2278 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
2279 backgroundColor.a);
2280}
2281
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002282TEST_P(RenderEngineTest, cleanupPostRender_cleansUpOnce) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002283 if (!GetParam()->typeSupported()) {
2284 GTEST_SKIP();
2285 }
Alec Mouric0aae732021-01-12 13:32:18 -08002286 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002287
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002288 renderengine::DisplaySettings settings;
2289 settings.physicalDisplay = fullscreenRect();
2290 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002291 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002292
Sally Qi59a9f502021-10-12 18:53:23 +00002293 std::vector<renderengine::LayerSettings> layers;
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002294 renderengine::LayerSettings layer;
2295 layer.geometry.boundaries = fullscreenRect().toFloatRect();
2296 BufferSourceVariant<ForceOpaqueBufferVariant>::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
2297 layer.alpha = 1.0;
Sally Qi59a9f502021-10-12 18:53:23 +00002298 layers.push_back(layer);
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002299
Patrick Williams2e9748f2022-08-09 22:48:18 +00002300 ftl::Future<FenceResult> futureOne =
Sally Qi4cabdd02021-08-05 16:45:57 -07002301 mRE->drawLayers(settings, layers, mBuffer, true, base::unique_fd());
Patrick Williams2e9748f2022-08-09 22:48:18 +00002302 ASSERT_TRUE(futureOne.valid());
2303 auto resultOne = futureOne.get();
2304 ASSERT_TRUE(resultOne.ok());
2305 auto fenceOne = resultOne.value();
Sally Qi4cabdd02021-08-05 16:45:57 -07002306
Patrick Williams2e9748f2022-08-09 22:48:18 +00002307 ftl::Future<FenceResult> futureTwo =
2308 mRE->drawLayers(settings, layers, mBuffer, true, base::unique_fd(fenceOne->dup()));
2309 ASSERT_TRUE(futureTwo.valid());
2310 auto resultTwo = futureTwo.get();
2311 ASSERT_TRUE(resultTwo.ok());
2312 auto fenceTwo = resultTwo.value();
2313 fenceTwo->waitForever(LOG_TAG);
Derek Sollenbergerec411212021-08-25 10:54:47 -04002314
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002315 // Only cleanup the first time.
Ian Elliott1f0911e2022-09-09 16:31:47 -06002316 if (mRE->canSkipPostRenderCleanup()) {
2317 // Skia's Vk backend may keep the texture alive beyond drawLayersInternal, so
2318 // it never gets added to the cleanup list. In those cases, we can skip.
2319 EXPECT_TRUE(GetParam()->type() == renderengine::RenderEngine::RenderEngineType::SKIA_VK);
2320 } else {
2321 mRE->cleanupPostRender();
2322 EXPECT_TRUE(mRE->canSkipPostRenderCleanup());
2323 }
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002324}
2325
Ana Krulecf9a15d92020-12-11 08:35:00 -08002326TEST_P(RenderEngineTest, testRoundedCornersCrop) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002327 if (!GetParam()->typeSupported()) {
2328 GTEST_SKIP();
2329 }
Alec Mouric0aae732021-01-12 13:32:18 -08002330 initializeRenderEngine();
Ana Krulecf9a15d92020-12-11 08:35:00 -08002331
2332 renderengine::DisplaySettings settings;
2333 settings.physicalDisplay = fullscreenRect();
2334 settings.clip = fullscreenRect();
2335 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2336
Sally Qi59a9f502021-10-12 18:53:23 +00002337 std::vector<renderengine::LayerSettings> layers;
Ana Krulecf9a15d92020-12-11 08:35:00 -08002338
2339 renderengine::LayerSettings redLayer;
2340 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2341 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002342 redLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
2343
Ana Krulecf9a15d92020-12-11 08:35:00 -08002344 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2345 // Red background.
2346 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2347 redLayer.alpha = 1.0f;
2348
Sally Qi59a9f502021-10-12 18:53:23 +00002349 layers.push_back(redLayer);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002350
2351 // Green layer with 1/3 size.
2352 renderengine::LayerSettings greenLayer;
2353 greenLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2354 greenLayer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002355 greenLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
Ana Krulecf9a15d92020-12-11 08:35:00 -08002356 // Bottom right corner is not going to be rounded.
2357 greenLayer.geometry.roundedCornersCrop =
2358 Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3, DEFAULT_DISPLAY_HEIGHT,
2359 DEFAULT_DISPLAY_HEIGHT)
2360 .toFloatRect();
2361 greenLayer.source.solidColor = half3(0.0f, 1.0f, 0.0f);
2362 greenLayer.alpha = 1.0f;
2363
Sally Qi59a9f502021-10-12 18:53:23 +00002364 layers.push_back(greenLayer);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002365
Alec Mouric0aae732021-01-12 13:32:18 -08002366 invokeDraw(settings, layers);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002367
2368 // Corners should be ignored...
2369 // Screen size: width is 128, height is 256.
2370 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 0);
2371 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, 0, DEFAULT_DISPLAY_WIDTH, 1), 0, 0, 0, 0);
2372 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT - 1, 1, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
2373 // Bottom right corner is kept out of the clipping, and it's green.
2374 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1,
2375 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
2376 0, 255, 0, 255);
2377}
2378
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002379TEST_P(RenderEngineTest, testRoundedCornersParentCrop) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002380 if (!GetParam()->typeSupported()) {
2381 GTEST_SKIP();
2382 }
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002383 initializeRenderEngine();
2384
2385 renderengine::DisplaySettings settings;
2386 settings.physicalDisplay = fullscreenRect();
2387 settings.clip = fullscreenRect();
2388 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2389
Sally Qi59a9f502021-10-12 18:53:23 +00002390 std::vector<renderengine::LayerSettings> layers;
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002391
2392 renderengine::LayerSettings redLayer;
2393 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2394 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002395 redLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002396 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2397 // Red background.
2398 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2399 redLayer.alpha = 1.0f;
2400
Sally Qi59a9f502021-10-12 18:53:23 +00002401 layers.push_back(redLayer);
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002402
2403 // Green layer with 1/2 size with parent crop rect.
2404 renderengine::LayerSettings greenLayer = redLayer;
2405 greenLayer.geometry.boundaries =
2406 FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT / 2);
2407 greenLayer.source.solidColor = half3(0.0f, 1.0f, 0.0f);
2408
Sally Qi59a9f502021-10-12 18:53:23 +00002409 layers.push_back(greenLayer);
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002410
2411 invokeDraw(settings, layers);
2412
2413 // Due to roundedCornersRadius, the corners are untouched.
2414 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2415 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2416 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2417 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2418
2419 // top middle should be green and the bottom middle red
2420 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, 0), 0, 255, 0, 255);
2421 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0, 255);
2422
2423 // the bottom edge of the green layer should not be rounded
2424 expectBufferColor(Point(0, (DEFAULT_DISPLAY_HEIGHT / 2) - 1), 0, 255, 0, 255);
2425}
2426
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002427TEST_P(RenderEngineTest, testRoundedCornersParentCropSmallBounds) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002428 if (!GetParam()->typeSupported()) {
2429 GTEST_SKIP();
2430 }
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002431 initializeRenderEngine();
2432
2433 renderengine::DisplaySettings settings;
2434 settings.physicalDisplay = fullscreenRect();
2435 settings.clip = fullscreenRect();
2436 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2437
Sally Qi59a9f502021-10-12 18:53:23 +00002438 std::vector<renderengine::LayerSettings> layers;
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002439
2440 renderengine::LayerSettings redLayer;
2441 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2442 redLayer.geometry.boundaries = FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, 32);
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002443 redLayer.geometry.roundedCornersRadius = {64.0f, 64.0f};
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002444 redLayer.geometry.roundedCornersCrop = FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, 128);
2445 // Red background.
2446 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2447 redLayer.alpha = 1.0f;
2448
Sally Qi59a9f502021-10-12 18:53:23 +00002449 layers.push_back(redLayer);
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002450 invokeDraw(settings, layers);
2451
2452 // Due to roundedCornersRadius, the top corners are untouched.
2453 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2454 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2455
2456 // ensure that the entire height of the red layer was clipped by the rounded corners crop.
2457 expectBufferColor(Point(0, 31), 0, 0, 0, 0);
2458 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 31), 0, 0, 0, 0);
2459
2460 // the bottom middle should be red
2461 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, 31), 255, 0, 0, 255);
2462}
2463
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002464TEST_P(RenderEngineTest, testRoundedCornersXY) {
2465 if (GetParam()->type() != renderengine::RenderEngine::RenderEngineType::SKIA_GL) {
2466 GTEST_SKIP();
2467 }
2468
2469 initializeRenderEngine();
2470
2471 renderengine::DisplaySettings settings;
2472 settings.physicalDisplay = fullscreenRect();
2473 settings.clip = fullscreenRect();
2474 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2475
2476 std::vector<renderengine::LayerSettings> layers;
2477
2478 renderengine::LayerSettings redLayer;
2479 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2480 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
2481 redLayer.geometry.roundedCornersRadius = {5.0f, 20.0f};
2482 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2483 // Red background.
2484 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2485 redLayer.alpha = 1.0f;
2486
2487 layers.push_back(redLayer);
2488
2489 invokeDraw(settings, layers);
2490
2491 // Due to roundedCornersRadius, the corners are untouched.
2492 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2493 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2494 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2495 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2496
2497 // Y-axis draws a larger radius, check that its untouched as well
2498 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 5), 0, 0, 0, 0);
2499 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 5), 0, 0, 0, 0);
2500 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 5), 0, 0, 0, 0);
2501 expectBufferColor(Point(0, 5), 0, 0, 0, 0);
2502
2503 // middle should be red
2504 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0, 255);
2505}
2506
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002507TEST_P(RenderEngineTest, testClear) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002508 if (!GetParam()->typeSupported()) {
2509 GTEST_SKIP();
2510 }
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002511 initializeRenderEngine();
2512
2513 const auto rect = fullscreenRect();
2514 const renderengine::DisplaySettings display{
2515 .physicalDisplay = rect,
2516 .clip = rect,
2517 };
2518
2519 const renderengine::LayerSettings redLayer{
2520 .geometry.boundaries = rect.toFloatRect(),
2521 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
2522 .alpha = 1.0f,
2523 };
2524
2525 // This mimics prepareClearClientComposition. This layer should overwrite
2526 // the redLayer, so that the buffer is transparent, rather than red.
2527 const renderengine::LayerSettings clearLayer{
2528 .geometry.boundaries = rect.toFloatRect(),
2529 .source.solidColor = half3(0.0f, 0.0f, 0.0f),
2530 .alpha = 0.0f,
2531 .disableBlending = true,
2532 };
2533
Sally Qi59a9f502021-10-12 18:53:23 +00002534 std::vector<renderengine::LayerSettings> layers{redLayer, clearLayer};
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002535 invokeDraw(display, layers);
2536 expectBufferColor(rect, 0, 0, 0, 0);
2537}
2538
2539TEST_P(RenderEngineTest, testDisableBlendingBuffer) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002540 if (!GetParam()->typeSupported()) {
2541 GTEST_SKIP();
2542 }
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002543 initializeRenderEngine();
2544
2545 const auto rect = Rect(0, 0, 1, 1);
2546 const renderengine::DisplaySettings display{
2547 .physicalDisplay = rect,
2548 .clip = rect,
2549 };
2550
2551 const renderengine::LayerSettings redLayer{
2552 .geometry.boundaries = rect.toFloatRect(),
2553 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
2554 .alpha = 1.0f,
2555 };
2556
2557 // The next layer will overwrite redLayer with a GraphicBuffer that is green
2558 // applied with a translucent alpha.
Alec Mouria90a5702021-04-16 16:36:21 +00002559 const auto buf = allocateSourceBuffer(1, 1);
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002560 {
2561 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00002562 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2563 reinterpret_cast<void**>(&pixels));
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002564 pixels[0] = 0;
2565 pixels[1] = 255;
2566 pixels[2] = 0;
2567 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00002568 buf->getBuffer()->unlock();
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002569 }
2570
2571 const renderengine::LayerSettings greenLayer{
2572 .geometry.boundaries = rect.toFloatRect(),
2573 .source =
2574 renderengine::PixelSource{
2575 .buffer =
2576 renderengine::Buffer{
2577 .buffer = buf,
2578 .usePremultipliedAlpha = true,
2579 },
2580 },
2581 .alpha = 0.5f,
2582 .disableBlending = true,
2583 };
2584
Sally Qi59a9f502021-10-12 18:53:23 +00002585 std::vector<renderengine::LayerSettings> layers{redLayer, greenLayer};
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002586 invokeDraw(display, layers);
2587 expectBufferColor(rect, 0, 128, 0, 128);
2588}
2589
Tianhao Yao67dd7122022-02-22 17:48:33 +00002590TEST_P(RenderEngineTest, testBorder) {
2591 if (GetParam()->type() != renderengine::RenderEngine::RenderEngineType::SKIA_GL) {
2592 GTEST_SKIP();
2593 }
2594
2595 if (!GetParam()->useColorManagement()) {
2596 GTEST_SKIP();
2597 }
2598
2599 initializeRenderEngine();
2600
2601 const ui::Dataspace dataspace = ui::Dataspace::V0_SRGB;
2602
2603 const auto displayRect = Rect(1080, 2280);
2604 renderengine::DisplaySettings display{
2605 .physicalDisplay = displayRect,
2606 .clip = displayRect,
2607 .outputDataspace = dataspace,
2608 };
2609 display.borderInfoList.clear();
2610 renderengine::BorderRenderInfo info;
2611 info.combinedRegion = Region(Rect(99, 99, 199, 199));
Tianhao Yao10cea3c2022-03-30 01:37:22 +00002612 info.width = 20.0f;
2613 info.color = half4{1.0f, 128.0f / 255.0f, 0.0f, 1.0f};
Tianhao Yao67dd7122022-02-22 17:48:33 +00002614 display.borderInfoList.emplace_back(info);
2615
2616 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2617 const renderengine::LayerSettings greenLayer{
2618 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2619 .source =
2620 renderengine::PixelSource{
2621 .buffer =
2622 renderengine::Buffer{
2623 .buffer = greenBuffer,
2624 .usePremultipliedAlpha = true,
2625 },
2626 },
2627 .alpha = 1.0f,
2628 .sourceDataspace = dataspace,
2629 .whitePointNits = 200.f,
2630 };
2631
2632 std::vector<renderengine::LayerSettings> layers;
2633 layers.emplace_back(greenLayer);
2634 invokeDraw(display, layers);
2635
2636 expectBufferColor(Rect(99, 99, 101, 101), 255, 128, 0, 255, 1);
2637}
2638
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002639TEST_P(RenderEngineTest, testDimming) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002640 if (!GetParam()->typeSupported()) {
2641 GTEST_SKIP();
2642 }
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002643 initializeRenderEngine();
2644
Alec Mouri85065692022-03-18 00:58:26 +00002645 const ui::Dataspace dataspace = ui::Dataspace::V0_SRGB_LINEAR;
2646
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002647 const auto displayRect = Rect(3, 1);
2648 const renderengine::DisplaySettings display{
2649 .physicalDisplay = displayRect,
2650 .clip = displayRect,
Alec Mouri85065692022-03-18 00:58:26 +00002651 .outputDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002652 .targetLuminanceNits = 1000.f,
2653 };
2654
2655 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2656 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2657 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2658
2659 const renderengine::LayerSettings greenLayer{
2660 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2661 .source =
2662 renderengine::PixelSource{
2663 .buffer =
2664 renderengine::Buffer{
2665 .buffer = greenBuffer,
2666 .usePremultipliedAlpha = true,
2667 },
2668 },
2669 .alpha = 1.0f,
Alec Mouri85065692022-03-18 00:58:26 +00002670 .sourceDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002671 .whitePointNits = 200.f,
2672 };
2673
2674 const renderengine::LayerSettings blueLayer{
2675 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2676 .source =
2677 renderengine::PixelSource{
2678 .buffer =
2679 renderengine::Buffer{
2680 .buffer = blueBuffer,
2681 .usePremultipliedAlpha = true,
2682 },
2683 },
2684 .alpha = 1.0f,
Alec Mouri85065692022-03-18 00:58:26 +00002685 .sourceDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002686 .whitePointNits = 1000.f / 51.f,
2687 };
2688
2689 const renderengine::LayerSettings redLayer{
2690 .geometry.boundaries = FloatRect(2.f, 0.f, 3.f, 1.f),
2691 .source =
2692 renderengine::PixelSource{
2693 .buffer =
2694 renderengine::Buffer{
2695 .buffer = redBuffer,
2696 .usePremultipliedAlpha = true,
2697 },
2698 },
2699 .alpha = 1.0f,
Alec Mouri85065692022-03-18 00:58:26 +00002700 .sourceDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002701 // When the white point is not set for a layer, just ignore it and treat it as the same
2702 // as the max layer
2703 .whitePointNits = -1.f,
2704 };
2705
2706 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer, redLayer};
2707 invokeDraw(display, layers);
2708
2709 expectBufferColor(Rect(1, 1), 0, 51, 0, 255, 1);
2710 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 5, 255, 1);
2711 expectBufferColor(Rect(2, 0, 3, 1), 51, 0, 0, 255, 1);
2712}
2713
Alec Mouri85065692022-03-18 00:58:26 +00002714TEST_P(RenderEngineTest, testDimming_inGammaSpace) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002715 if (!GetParam()->typeSupported()) {
2716 GTEST_SKIP();
2717 }
Alec Mouri85065692022-03-18 00:58:26 +00002718 initializeRenderEngine();
2719
2720 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2721 ui::Dataspace::TRANSFER_GAMMA2_2 |
2722 ui::Dataspace::RANGE_FULL);
2723
2724 const auto displayRect = Rect(3, 1);
2725 const renderengine::DisplaySettings display{
2726 .physicalDisplay = displayRect,
2727 .clip = displayRect,
2728 .outputDataspace = dataspace,
2729 .targetLuminanceNits = 1000.f,
2730 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2731 };
2732
2733 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2734 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2735 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2736
2737 const renderengine::LayerSettings greenLayer{
2738 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2739 .source =
2740 renderengine::PixelSource{
2741 .buffer =
2742 renderengine::Buffer{
2743 .buffer = greenBuffer,
2744 .usePremultipliedAlpha = true,
2745 },
2746 },
2747 .alpha = 1.0f,
2748 .sourceDataspace = dataspace,
2749 .whitePointNits = 200.f,
2750 };
2751
2752 const renderengine::LayerSettings blueLayer{
2753 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2754 .source =
2755 renderengine::PixelSource{
2756 .buffer =
2757 renderengine::Buffer{
2758 .buffer = blueBuffer,
2759 .usePremultipliedAlpha = true,
2760 },
2761 },
2762 .alpha = 1.0f,
2763 .sourceDataspace = dataspace,
2764 .whitePointNits = 1000.f / 51.f,
2765 };
2766
2767 const renderengine::LayerSettings redLayer{
2768 .geometry.boundaries = FloatRect(2.f, 0.f, 3.f, 1.f),
2769 .source =
2770 renderengine::PixelSource{
2771 .buffer =
2772 renderengine::Buffer{
2773 .buffer = redBuffer,
2774 .usePremultipliedAlpha = true,
2775 },
2776 },
2777 .alpha = 1.0f,
2778 .sourceDataspace = dataspace,
2779 // When the white point is not set for a layer, just ignore it and treat it as the same
2780 // as the max layer
2781 .whitePointNits = -1.f,
2782 };
2783
2784 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer, redLayer};
2785 invokeDraw(display, layers);
2786
2787 expectBufferColor(Rect(1, 1), 0, 122, 0, 255, 1);
2788 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 42, 255, 1);
2789 expectBufferColor(Rect(2, 0, 3, 1), 122, 0, 0, 255, 1);
2790}
2791
Alec Mouri9bcd1d12022-04-21 22:16:56 +00002792TEST_P(RenderEngineTest, testDimming_inGammaSpace_withDisplayColorTransform) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002793 if (!GetParam()->typeSupported()) {
2794 GTEST_SKIP();
2795 }
Alec Mouri9bcd1d12022-04-21 22:16:56 +00002796 initializeRenderEngine();
2797
2798 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2799 ui::Dataspace::TRANSFER_GAMMA2_2 |
2800 ui::Dataspace::RANGE_FULL);
2801
2802 const auto displayRect = Rect(3, 1);
2803 const renderengine::DisplaySettings display{
2804 .physicalDisplay = displayRect,
2805 .clip = displayRect,
2806 .outputDataspace = dataspace,
2807 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
2808 .targetLuminanceNits = 1000.f,
2809 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2810 };
2811
2812 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2813 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2814 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2815
2816 const renderengine::LayerSettings greenLayer{
2817 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2818 .source =
2819 renderengine::PixelSource{
2820 .buffer =
2821 renderengine::Buffer{
2822 .buffer = greenBuffer,
2823 .usePremultipliedAlpha = true,
2824 },
2825 },
2826 .alpha = 1.0f,
2827 .sourceDataspace = dataspace,
2828 .whitePointNits = 200.f,
2829 };
2830
2831 const renderengine::LayerSettings redLayer{
2832 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2833 .source =
2834 renderengine::PixelSource{
2835 .buffer =
2836 renderengine::Buffer{
2837 .buffer = redBuffer,
2838 .usePremultipliedAlpha = true,
2839 },
2840 },
2841 .alpha = 1.0f,
2842 .sourceDataspace = dataspace,
2843 // When the white point is not set for a layer, just ignore it and treat it as the same
2844 // as the max layer
2845 .whitePointNits = -1.f,
2846 };
2847
2848 std::vector<renderengine::LayerSettings> layers{greenLayer, redLayer};
2849 invokeDraw(display, layers);
2850
2851 expectBufferColor(Rect(1, 1), 0, 0, 0, 255, 1);
2852 expectBufferColor(Rect(1, 0, 2, 1), 0, 122, 0, 255, 1);
2853}
2854
2855TEST_P(RenderEngineTest, testDimming_inGammaSpace_withDisplayColorTransform_deviceHandles) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002856 if (!GetParam()->typeSupported()) {
2857 GTEST_SKIP();
2858 }
Alec Mouri9bcd1d12022-04-21 22:16:56 +00002859 initializeRenderEngine();
2860
2861 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2862 ui::Dataspace::TRANSFER_GAMMA2_2 |
2863 ui::Dataspace::RANGE_FULL);
2864
2865 const auto displayRect = Rect(3, 1);
2866 const renderengine::DisplaySettings display{
2867 .physicalDisplay = displayRect,
2868 .clip = displayRect,
2869 .outputDataspace = dataspace,
2870 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
2871 .deviceHandlesColorTransform = true,
2872 .targetLuminanceNits = 1000.f,
2873 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2874 };
2875
2876 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2877 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2878 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2879
2880 const renderengine::LayerSettings greenLayer{
2881 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2882 .source =
2883 renderengine::PixelSource{
2884 .buffer =
2885 renderengine::Buffer{
2886 .buffer = greenBuffer,
2887 .usePremultipliedAlpha = true,
2888 },
2889 },
2890 .alpha = 1.0f,
2891 .sourceDataspace = dataspace,
2892 .whitePointNits = 200.f,
2893 };
2894
2895 const renderengine::LayerSettings redLayer{
2896 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2897 .source =
2898 renderengine::PixelSource{
2899 .buffer =
2900 renderengine::Buffer{
2901 .buffer = redBuffer,
2902 .usePremultipliedAlpha = true,
2903 },
2904 },
2905 .alpha = 1.0f,
2906 .sourceDataspace = dataspace,
2907 // When the white point is not set for a layer, just ignore it and treat it as the same
2908 // as the max layer
2909 .whitePointNits = -1.f,
2910 };
2911
2912 std::vector<renderengine::LayerSettings> layers{greenLayer, redLayer};
2913 invokeDraw(display, layers);
2914
2915 expectBufferColor(Rect(1, 1), 0, 122, 0, 255, 1);
2916 expectBufferColor(Rect(1, 0, 2, 1), 122, 0, 0, 255, 1);
2917}
2918
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002919TEST_P(RenderEngineTest, testDimming_withoutTargetLuminance) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002920 if (!GetParam()->typeSupported()) {
2921 GTEST_SKIP();
2922 }
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002923 initializeRenderEngine();
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002924
2925 const auto displayRect = Rect(2, 1);
2926 const renderengine::DisplaySettings display{
2927 .physicalDisplay = displayRect,
2928 .clip = displayRect,
2929 .outputDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2930 .targetLuminanceNits = -1.f,
2931 };
2932
2933 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2934 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2935
2936 const renderengine::LayerSettings greenLayer{
2937 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2938 .source =
2939 renderengine::PixelSource{
2940 .buffer =
2941 renderengine::Buffer{
2942 .buffer = greenBuffer,
2943 .usePremultipliedAlpha = true,
2944 },
2945 },
2946 .alpha = 1.0f,
2947 .sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2948 .whitePointNits = 200.f,
2949 };
2950
2951 const renderengine::LayerSettings blueLayer{
2952 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2953 .source =
2954 renderengine::PixelSource{
2955 .buffer =
2956 renderengine::Buffer{
2957 .buffer = blueBuffer,
2958 .usePremultipliedAlpha = true,
2959 },
2960 },
2961 .alpha = 1.0f,
2962 .sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2963 .whitePointNits = 1000.f,
2964 };
2965
2966 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer};
2967 invokeDraw(display, layers);
2968
2969 expectBufferColor(Rect(1, 1), 0, 51, 0, 255, 1);
2970 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 255, 255);
2971}
2972
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002973TEST_P(RenderEngineTest, test_isOpaque) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002974 if (!GetParam()->typeSupported()) {
2975 GTEST_SKIP();
2976 }
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002977 initializeRenderEngine();
2978
2979 const auto rect = Rect(0, 0, 1, 1);
2980 const renderengine::DisplaySettings display{
2981 .physicalDisplay = rect,
2982 .clip = rect,
2983 .outputDataspace = ui::Dataspace::DISPLAY_P3,
2984 };
2985
2986 // Create an unpremul buffer that is green with no alpha. Using isOpaque
2987 // should make the green show.
2988 const auto buf = allocateSourceBuffer(1, 1);
2989 {
2990 uint8_t* pixels;
2991 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2992 reinterpret_cast<void**>(&pixels));
2993 pixels[0] = 0;
2994 pixels[1] = 255;
2995 pixels[2] = 0;
2996 pixels[3] = 0;
2997 buf->getBuffer()->unlock();
2998 }
2999
3000 const renderengine::LayerSettings greenLayer{
3001 .geometry.boundaries = rect.toFloatRect(),
3002 .source =
3003 renderengine::PixelSource{
3004 .buffer =
3005 renderengine::Buffer{
3006 .buffer = buf,
3007 // Although the pixels are not
3008 // premultiplied in practice, this
3009 // matches the input we see.
3010 .usePremultipliedAlpha = true,
3011 .isOpaque = true,
3012 },
3013 },
3014 .alpha = 1.0f,
3015 };
3016
Sally Qi59a9f502021-10-12 18:53:23 +00003017 std::vector<renderengine::LayerSettings> layers{greenLayer};
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04003018 invokeDraw(display, layers);
3019
3020 if (GetParam()->useColorManagement()) {
3021 expectBufferColor(rect, 117, 251, 76, 255);
3022 } else {
3023 expectBufferColor(rect, 0, 255, 0, 255);
3024 }
3025}
Alec Mouri4049b532021-10-15 20:59:33 -07003026
Alec Mouri4049b532021-10-15 20:59:33 -07003027TEST_P(RenderEngineTest, test_tonemapPQMatches) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003028 if (!GetParam()->typeSupported() || !GetParam()->useColorManagement()) {
Alec Mouri5a493722022-01-26 16:43:02 -08003029 GTEST_SKIP();
Alec Mouri4049b532021-10-15 20:59:33 -07003030 }
3031
Alec Mouri4049b532021-10-15 20:59:33 -07003032 initializeRenderEngine();
3033
Alec Mouri5a493722022-01-26 16:43:02 -08003034 tonemap(
3035 static_cast<ui::Dataspace>(HAL_DATASPACE_STANDARD_BT2020 |
3036 HAL_DATASPACE_TRANSFER_ST2084 | HAL_DATASPACE_RANGE_FULL),
3037 [](vec3 color) { return EOTF_PQ(color); },
3038 [](vec3 color, float) {
3039 static constexpr float kMaxPQLuminance = 10000.f;
3040 return color * kMaxPQLuminance;
3041 });
3042}
Alec Mouri4049b532021-10-15 20:59:33 -07003043
Alec Mouri5a493722022-01-26 16:43:02 -08003044TEST_P(RenderEngineTest, test_tonemapHLGMatches) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003045 if (!GetParam()->typeSupported() || !GetParam()->useColorManagement()) {
Alec Mouri5a493722022-01-26 16:43:02 -08003046 GTEST_SKIP();
Alec Mouri4049b532021-10-15 20:59:33 -07003047 }
3048
Alec Mouri5a493722022-01-26 16:43:02 -08003049 initializeRenderEngine();
Alec Mouri4049b532021-10-15 20:59:33 -07003050
Alec Mouri5a493722022-01-26 16:43:02 -08003051 tonemap(
3052 static_cast<ui::Dataspace>(HAL_DATASPACE_STANDARD_BT2020 | HAL_DATASPACE_TRANSFER_HLG |
3053 HAL_DATASPACE_RANGE_FULL),
3054 [](vec3 color) { return EOTF_HLG(color); },
3055 [](vec3 color, float currentLuminaceNits) {
3056 static constexpr float kMaxHLGLuminance = 1000.f;
Alec Mouri7a577452022-03-04 23:41:38 +00003057 return color * kMaxHLGLuminance;
Alec Mouri5a493722022-01-26 16:43:02 -08003058 });
Alec Mouri4049b532021-10-15 20:59:33 -07003059}
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -05003060
3061TEST_P(RenderEngineTest, r8_behaves_as_mask) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003062 if (!GetParam()->typeSupported()) {
3063 GTEST_SKIP();
3064 }
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -05003065 initializeRenderEngine();
3066
3067 const auto r8Buffer = allocateR8Buffer(2, 1);
3068 if (!r8Buffer) {
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003069 GTEST_SKIP() << "Test is only necessary on devices that support r8";
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -05003070 return;
3071 }
3072 {
3073 uint8_t* pixels;
3074 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
3075 reinterpret_cast<void**>(&pixels));
3076 // This will be drawn on top of a green buffer. We'll verify that 255
3077 // results in keeping the original green and 0 results in black.
3078 pixels[0] = 0;
3079 pixels[1] = 255;
3080 r8Buffer->getBuffer()->unlock();
3081 }
3082
3083 const auto rect = Rect(0, 0, 2, 1);
3084 const renderengine::DisplaySettings display{
3085 .physicalDisplay = rect,
3086 .clip = rect,
3087 .outputDataspace = ui::Dataspace::SRGB,
3088 };
3089
3090 const auto greenBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(0, 255, 0, 255));
3091 const renderengine::LayerSettings greenLayer{
3092 .geometry.boundaries = rect.toFloatRect(),
3093 .source =
3094 renderengine::PixelSource{
3095 .buffer =
3096 renderengine::Buffer{
3097 .buffer = greenBuffer,
3098 },
3099 },
3100 .alpha = 1.0f,
3101 };
3102 const renderengine::LayerSettings r8Layer{
3103 .geometry.boundaries = rect.toFloatRect(),
3104 .source =
3105 renderengine::PixelSource{
3106 .buffer =
3107 renderengine::Buffer{
3108 .buffer = r8Buffer,
3109 },
3110 },
3111 .alpha = 1.0f,
3112 };
3113
3114 std::vector<renderengine::LayerSettings> layers{greenLayer, r8Layer};
3115 invokeDraw(display, layers);
3116
3117 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 255);
3118 expectBufferColor(Rect(1, 0, 2, 1), 0, 255, 0, 255);
3119}
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003120
3121TEST_P(RenderEngineTest, r8_respects_color_transform) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003122 if (!GetParam()->typeSupported()) {
3123 GTEST_SKIP();
3124 }
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003125 initializeRenderEngine();
3126
3127 const auto r8Buffer = allocateR8Buffer(2, 1);
3128 if (!r8Buffer) {
3129 GTEST_SKIP() << "Test is only necessary on devices that support r8";
3130 return;
3131 }
3132 {
3133 uint8_t* pixels;
3134 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
3135 reinterpret_cast<void**>(&pixels));
3136 pixels[0] = 0;
3137 pixels[1] = 255;
3138 r8Buffer->getBuffer()->unlock();
3139 }
3140
3141 const auto rect = Rect(0, 0, 2, 1);
3142 const renderengine::DisplaySettings display{
3143 .physicalDisplay = rect,
3144 .clip = rect,
3145 .outputDataspace = ui::Dataspace::SRGB,
3146 // Verify that the R8 layer respects the color transform when
3147 // deviceHandlesColorTransform is false. This transform converts
3148 // pure red to pure green. That will occur when the R8 buffer is
3149 // 255. When the R8 buffer is 0, it will still change to black, as
3150 // with r8_behaves_as_mask.
Alec Mouri9bcd1d12022-04-21 22:16:56 +00003151 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003152 .deviceHandlesColorTransform = false,
3153 };
3154
3155 const auto redBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(255, 0, 0, 255));
3156 const renderengine::LayerSettings redLayer{
3157 .geometry.boundaries = rect.toFloatRect(),
3158 .source =
3159 renderengine::PixelSource{
3160 .buffer =
3161 renderengine::Buffer{
3162 .buffer = redBuffer,
3163 },
3164 },
3165 .alpha = 1.0f,
3166 };
3167 const renderengine::LayerSettings r8Layer{
3168 .geometry.boundaries = rect.toFloatRect(),
3169 .source =
3170 renderengine::PixelSource{
3171 .buffer =
3172 renderengine::Buffer{
3173 .buffer = r8Buffer,
3174 },
3175 },
3176 .alpha = 1.0f,
3177 };
3178
3179 std::vector<renderengine::LayerSettings> layers{redLayer, r8Layer};
3180 invokeDraw(display, layers);
3181
3182 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 255);
3183 expectBufferColor(Rect(1, 0, 2, 1), 0, 255, 0, 255);
3184}
3185
3186TEST_P(RenderEngineTest, r8_respects_color_transform_when_device_handles) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003187 if (!GetParam()->typeSupported()) {
3188 GTEST_SKIP();
3189 }
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003190 initializeRenderEngine();
3191
3192 const auto r8Buffer = allocateR8Buffer(2, 1);
3193 if (!r8Buffer) {
3194 GTEST_SKIP() << "Test is only necessary on devices that support r8";
3195 return;
3196 }
3197 {
3198 uint8_t* pixels;
3199 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
3200 reinterpret_cast<void**>(&pixels));
3201 pixels[0] = 0;
3202 pixels[1] = 255;
3203 r8Buffer->getBuffer()->unlock();
3204 }
3205
3206 const auto rect = Rect(0, 0, 2, 1);
3207 const renderengine::DisplaySettings display{
3208 .physicalDisplay = rect,
3209 .clip = rect,
3210 .outputDataspace = ui::Dataspace::SRGB,
3211 // If deviceHandlesColorTransform is true, pixels where the A8
3212 // buffer is opaque are unaffected. If the colorTransform is
3213 // invertible, pixels where the A8 buffer are transparent have the
3214 // inverse applied to them so that the DPU will convert them back to
3215 // black. Test with an arbitrary, invertible matrix.
3216 .colorTransform = mat4(1, 0, 0, 2,
3217 3, 1, 2, 5,
3218 0, 5, 3, 0,
3219 0, 1, 0, 2),
3220 .deviceHandlesColorTransform = true,
3221 };
3222
3223 const auto redBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(255, 0, 0, 255));
3224 const renderengine::LayerSettings redLayer{
3225 .geometry.boundaries = rect.toFloatRect(),
3226 .source =
3227 renderengine::PixelSource{
3228 .buffer =
3229 renderengine::Buffer{
3230 .buffer = redBuffer,
3231 },
3232 },
3233 .alpha = 1.0f,
3234 };
3235 const renderengine::LayerSettings r8Layer{
3236 .geometry.boundaries = rect.toFloatRect(),
3237 .source =
3238 renderengine::PixelSource{
3239 .buffer =
3240 renderengine::Buffer{
3241 .buffer = r8Buffer,
3242 },
3243 },
3244 .alpha = 1.0f,
3245 };
3246
3247 std::vector<renderengine::LayerSettings> layers{redLayer, r8Layer};
3248 invokeDraw(display, layers);
3249
3250 expectBufferColor(Rect(1, 0, 2, 1), 255, 0, 0, 255); // Still red.
3251 expectBufferColor(Rect(0, 0, 1, 1), 0, 70, 0, 255);
3252}
Leon Scroggins III45be9182022-04-27 10:37:11 -04003253
3254TEST_P(RenderEngineTest, primeShaderCache) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003255 if (!GetParam()->typeSupported()) {
3256 GTEST_SKIP();
3257 }
Leon Scroggins III45be9182022-04-27 10:37:11 -04003258 initializeRenderEngine();
3259
3260 auto fut = mRE->primeCache();
3261 if (fut.valid()) {
3262 fut.wait();
3263 }
3264
3265 const int minimumExpectedShadersCompiled = GetParam()->useColorManagement() ? 60 : 30;
3266 ASSERT_GT(static_cast<skia::SkiaGLRenderEngine*>(mRE.get())->reportShadersCompiled(),
3267 minimumExpectedShadersCompiled);
3268}
Derek Sollenbergerd3f60652021-06-11 15:34:36 -04003269} // namespace renderengine
Alec Mouri6e57f682018-09-29 20:45:08 -07003270} // namespace android
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08003271
3272// TODO(b/129481165): remove the #pragma below and fix conversion issues
Marin Shalamanovbed7fd32020-12-21 20:02:20 +01003273#pragma clang diagnostic pop // ignored "-Wconversion -Wextra"