blob: 2fd2a3592742bd89003fe5805c90e86ff263983f [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;
Ian Elliott1f0911e2022-09-09 16:31:47 -0600110 virtual bool typeSupported() = 0;
Leon Scroggins III5ef55002024-01-25 10:51:45 -0500111 std::unique_ptr<renderengine::RenderEngine> createRenderEngine() {
112 renderengine::RenderEngineCreationArgs reCreationArgs =
113 renderengine::RenderEngineCreationArgs::Builder()
114 .setPixelFormat(static_cast<int>(ui::PixelFormat::RGBA_8888))
115 .setImageCacheSize(1)
116 .setEnableProtectedContext(false)
117 .setPrecacheToneMapperShaderOnly(false)
118 .setSupportsBackgroundBlur(true)
119 .setContextPriority(renderengine::RenderEngine::ContextPriority::MEDIUM)
120 .setRenderEngineType(type())
121 .build();
122 return renderengine::RenderEngine::create(reCreationArgs);
123 }
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800124};
125
Ian Elliott1f0911e2022-09-09 16:31:47 -0600126class SkiaVkRenderEngineFactory : public RenderEngineFactory {
127public:
128 std::string name() override { return "SkiaVkRenderEngineFactory"; }
129
130 renderengine::RenderEngine::RenderEngineType type() {
131 return renderengine::RenderEngine::RenderEngineType::SKIA_VK;
132 }
133
Ian Elliott1f0911e2022-09-09 16:31:47 -0600134 bool typeSupported() override {
135 return skia::SkiaVkRenderEngine::canSupportSkiaVkRenderEngine();
136 }
Ian Elliott1f0911e2022-09-09 16:31:47 -0600137};
138
Alec Mouri0eab3e82020-12-08 18:10:27 -0800139class SkiaGLESRenderEngineFactory : public RenderEngineFactory {
140public:
Alec Mouric0aae732021-01-12 13:32:18 -0800141 std::string name() override { return "SkiaGLRenderEngineFactory"; }
Alec Mouri0eab3e82020-12-08 18:10:27 -0800142
Alec Mouric0aae732021-01-12 13:32:18 -0800143 renderengine::RenderEngine::RenderEngineType type() {
144 return renderengine::RenderEngine::RenderEngineType::SKIA_GL;
145 }
146
Ian Elliott1f0911e2022-09-09 16:31:47 -0600147 bool typeSupported() override { return true; }
Alec Mouri0eab3e82020-12-08 18:10:27 -0800148};
149
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800150class RenderEngineTest : public ::testing::TestWithParam<std::shared_ptr<RenderEngineFactory>> {
151public:
Alec Mouria90a5702021-04-16 16:36:21 +0000152 std::shared_ptr<renderengine::ExternalTexture> allocateDefaultBuffer() {
153 return std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800154 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -0700155 ExternalTexture>(sp<GraphicBuffer>::
156 make(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT,
157 HAL_PIXEL_FORMAT_RGBA_8888, 1,
158 GRALLOC_USAGE_SW_READ_OFTEN |
159 GRALLOC_USAGE_SW_WRITE_OFTEN |
160 GRALLOC_USAGE_HW_RENDER |
161 GRALLOC_USAGE_HW_TEXTURE,
162 "output"),
Alec Mouria90a5702021-04-16 16:36:21 +0000163 *mRE,
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800164 renderengine::impl::ExternalTexture::Usage::READABLE |
165 renderengine::impl::ExternalTexture::Usage::
166 WRITEABLE);
Alec Mouri6e57f682018-09-29 20:45:08 -0700167 }
168
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800169 // Allocates a 1x1 buffer to fill with a solid color
Alec Mouria90a5702021-04-16 16:36:21 +0000170 std::shared_ptr<renderengine::ExternalTexture> allocateSourceBuffer(uint32_t width,
171 uint32_t height) {
172 return std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800173 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -0700174 ExternalTexture>(sp<GraphicBuffer>::
175 make(width, height, HAL_PIXEL_FORMAT_RGBA_8888, 1,
176 GRALLOC_USAGE_SW_READ_OFTEN |
177 GRALLOC_USAGE_SW_WRITE_OFTEN |
178 GRALLOC_USAGE_HW_TEXTURE,
179 "input"),
Alec Mouria90a5702021-04-16 16:36:21 +0000180 *mRE,
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800181 renderengine::impl::ExternalTexture::Usage::READABLE |
182 renderengine::impl::ExternalTexture::Usage::
183 WRITEABLE);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800184 }
185
Alec Mouricdf6cbc2021-11-01 17:21:15 -0700186 std::shared_ptr<renderengine::ExternalTexture> allocateAndFillSourceBuffer(uint32_t width,
187 uint32_t height,
188 ubyte4 color) {
189 const auto buffer = allocateSourceBuffer(width, height);
190 uint8_t* pixels;
191 buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
192 reinterpret_cast<void**>(&pixels));
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -0500193 for (uint32_t j = 0; j < height; j++) {
194 uint8_t* dst = pixels + (buffer->getBuffer()->getStride() * j * 4);
195 for (uint32_t i = 0; i < width; i++) {
196 dst[0] = color.r;
197 dst[1] = color.g;
198 dst[2] = color.b;
199 dst[3] = color.a;
200 dst += 4;
201 }
202 }
Alec Mouricdf6cbc2021-11-01 17:21:15 -0700203 buffer->getBuffer()->unlock();
204 return buffer;
205 }
206
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -0500207 std::shared_ptr<renderengine::ExternalTexture> allocateR8Buffer(int width, int height) {
Ady Abrahamd11bade2022-08-01 16:18:03 -0700208 const auto kUsageFlags =
209 static_cast<uint64_t>(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
210 GRALLOC_USAGE_HW_TEXTURE);
211 auto buffer =
212 sp<GraphicBuffer>::make(static_cast<uint32_t>(width), static_cast<uint32_t>(height),
213 android::PIXEL_FORMAT_R_8, 1u, kUsageFlags, "r8");
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -0500214 if (buffer->initCheck() != 0) {
215 // Devices are not required to support R8.
216 return nullptr;
217 }
218 return std::make_shared<
219 renderengine::impl::ExternalTexture>(std::move(buffer), *mRE,
220 renderengine::impl::ExternalTexture::Usage::
221 READABLE);
222 }
223
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800224 RenderEngineTest() {
225 const ::testing::TestInfo* const test_info =
226 ::testing::UnitTest::GetInstance()->current_test_info();
227 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800228 }
Alec Mouri1089aed2018-10-25 21:33:57 -0700229
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800230 ~RenderEngineTest() {
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800231 if (WRITE_BUFFER_TO_FILE_ON_FAILURE && ::testing::Test::HasFailure()) {
232 writeBufferToFile("/data/texture_out_");
233 }
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800234 const ::testing::TestInfo* const test_info =
235 ::testing::UnitTest::GetInstance()->current_test_info();
236 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800237 }
238
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800239 void writeBufferToFile(const char* basename) {
240 std::string filename(basename);
241 filename.append(::testing::UnitTest::GetInstance()->current_test_info()->name());
242 filename.append(".ppm");
243 std::ofstream file(filename.c_str(), std::ios::binary);
244 if (!file.is_open()) {
245 ALOGE("Unable to open file: %s", filename.c_str());
246 ALOGE("You may need to do: \"adb shell setenforce 0\" to enable "
247 "surfaceflinger to write debug images");
248 return;
249 }
250
Alec Mouri1089aed2018-10-25 21:33:57 -0700251 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +0000252 mBuffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
253 reinterpret_cast<void**>(&pixels));
Alec Mouri1089aed2018-10-25 21:33:57 -0700254
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800255 file << "P6\n";
Alec Mouria90a5702021-04-16 16:36:21 +0000256 file << mBuffer->getBuffer()->getWidth() << "\n";
257 file << mBuffer->getBuffer()->getHeight() << "\n";
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800258 file << 255 << "\n";
259
Alec Mouria90a5702021-04-16 16:36:21 +0000260 std::vector<uint8_t> outBuffer(mBuffer->getBuffer()->getWidth() *
261 mBuffer->getBuffer()->getHeight() * 3);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800262 auto outPtr = reinterpret_cast<uint8_t*>(outBuffer.data());
263
Alec Mouria90a5702021-04-16 16:36:21 +0000264 for (int32_t j = 0; j < mBuffer->getBuffer()->getHeight(); j++) {
265 const uint8_t* src = pixels + (mBuffer->getBuffer()->getStride() * j) * 4;
266 for (int32_t i = 0; i < mBuffer->getBuffer()->getWidth(); i++) {
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800267 // Only copy R, G and B components
268 outPtr[0] = src[0];
269 outPtr[1] = src[1];
270 outPtr[2] = src[2];
271 outPtr += 3;
272
273 src += 4;
274 }
275 }
276 file.write(reinterpret_cast<char*>(outBuffer.data()), outBuffer.size());
Alec Mouria90a5702021-04-16 16:36:21 +0000277 mBuffer->getBuffer()->unlock();
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800278 }
279
280 void expectBufferColor(const Region& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
281 size_t c;
282 Rect const* rect = region.getArray(&c);
283 for (size_t i = 0; i < c; i++, rect++) {
284 expectBufferColor(*rect, r, g, b, a);
285 }
286 }
287
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -0400288 void expectBufferColor(const Point& point, uint8_t r, uint8_t g, uint8_t b, uint8_t a,
289 uint8_t tolerance = 0) {
290 expectBufferColor(Rect(point.x, point.y, point.x + 1, point.y + 1), r, g, b, a, tolerance);
291 }
292
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800293 void expectBufferColor(const Rect& rect, uint8_t r, uint8_t g, uint8_t b, uint8_t a,
294 uint8_t tolerance = 0) {
Alec Mouri4049b532021-10-15 20:59:33 -0700295 auto generator = [=](Point) { return ubyte4(r, g, b, a); };
296 expectBufferColor(rect, generator, tolerance);
297 }
298
299 using ColorGenerator = std::function<ubyte4(Point location)>;
300
301 void expectBufferColor(const Rect& rect, ColorGenerator generator, uint8_t tolerance = 0) {
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800302 auto colorCompare = [tolerance](const uint8_t* colorA, const uint8_t* colorB) {
303 auto colorBitCompare = [tolerance](uint8_t a, uint8_t b) {
304 uint8_t tmp = a >= b ? a - b : b - a;
305 return tmp <= tolerance;
306 };
307 return std::equal(colorA, colorA + 4, colorB, colorBitCompare);
Alec Mouri1089aed2018-10-25 21:33:57 -0700308 };
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800309
Alec Mouri4049b532021-10-15 20:59:33 -0700310 expectBufferColor(rect, generator, colorCompare);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800311 }
312
Alec Mouri4049b532021-10-15 20:59:33 -0700313 void expectBufferColor(const Rect& region, ColorGenerator generator,
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800314 std::function<bool(const uint8_t* a, const uint8_t* b)> colorCompare) {
315 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +0000316 mBuffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
317 reinterpret_cast<void**>(&pixels));
Alec Mouri1089aed2018-10-25 21:33:57 -0700318 int32_t maxFails = 10;
319 int32_t fails = 0;
320 for (int32_t j = 0; j < region.getHeight(); j++) {
Alec Mouria90a5702021-04-16 16:36:21 +0000321 const uint8_t* src = pixels +
322 (mBuffer->getBuffer()->getStride() * (region.top + j) + region.left) * 4;
Alec Mouri1089aed2018-10-25 21:33:57 -0700323 for (int32_t i = 0; i < region.getWidth(); i++) {
Alec Mouri4049b532021-10-15 20:59:33 -0700324 const auto location = Point(region.left + i, region.top + j);
325 const ubyte4 colors = generator(location);
326 const uint8_t expected[4] = {colors.r, colors.g, colors.b, colors.a};
327 bool colorMatches = colorCompare(src, expected);
328 EXPECT_TRUE(colorMatches)
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -0400329 << GetParam()->name().c_str() << ": "
Alec Mouri4049b532021-10-15 20:59:33 -0700330 << "pixel @ (" << location.x << ", " << location.y << "): "
331 << "expected (" << static_cast<uint32_t>(colors.r) << ", "
332 << static_cast<uint32_t>(colors.g) << ", "
333 << static_cast<uint32_t>(colors.b) << ", "
334 << static_cast<uint32_t>(colors.a) << "), "
Alec Mouri1089aed2018-10-25 21:33:57 -0700335 << "got (" << static_cast<uint32_t>(src[0]) << ", "
336 << static_cast<uint32_t>(src[1]) << ", " << static_cast<uint32_t>(src[2])
337 << ", " << static_cast<uint32_t>(src[3]) << ")";
338 src += 4;
Alec Mouri4049b532021-10-15 20:59:33 -0700339 if (!colorMatches && ++fails >= maxFails) {
Alec Mouri1089aed2018-10-25 21:33:57 -0700340 break;
341 }
342 }
343 if (fails >= maxFails) {
344 break;
345 }
346 }
Alec Mouria90a5702021-04-16 16:36:21 +0000347 mBuffer->getBuffer()->unlock();
Alec Mouri1089aed2018-10-25 21:33:57 -0700348 }
349
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800350 void expectAlpha(const Rect& rect, uint8_t a) {
Alec Mouri4049b532021-10-15 20:59:33 -0700351 auto generator = [=](Point) { return ubyte4(0, 0, 0, a); };
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800352 auto colorCompare = [](const uint8_t* colorA, const uint8_t* colorB) {
353 return colorA[3] == colorB[3];
354 };
Alec Mouri4049b532021-10-15 20:59:33 -0700355 expectBufferColor(rect, generator, colorCompare);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800356 }
357
358 void expectShadowColor(const renderengine::LayerSettings& castingLayer,
Vishnu Naird9e4f462023-10-06 04:05:45 +0000359 const ShadowSettings& shadow, const ubyte4& casterColor,
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800360 const ubyte4& backgroundColor) {
361 const Rect casterRect(castingLayer.geometry.boundaries);
362 Region casterRegion = Region(casterRect);
Vishnu Nair50c0afe2022-07-11 15:04:07 -0700363 const float casterCornerRadius = (castingLayer.geometry.roundedCornersRadius.x +
364 castingLayer.geometry.roundedCornersRadius.y) /
365 2.0;
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800366 if (casterCornerRadius > 0.0f) {
367 // ignore the corners if a corner radius is set
368 Rect cornerRect(casterCornerRadius, casterCornerRadius);
369 casterRegion.subtractSelf(cornerRect.offsetTo(casterRect.left, casterRect.top));
370 casterRegion.subtractSelf(
371 cornerRect.offsetTo(casterRect.right - casterCornerRadius, casterRect.top));
372 casterRegion.subtractSelf(
373 cornerRect.offsetTo(casterRect.left, casterRect.bottom - casterCornerRadius));
374 casterRegion.subtractSelf(cornerRect.offsetTo(casterRect.right - casterCornerRadius,
375 casterRect.bottom - casterCornerRadius));
376 }
377
378 const float shadowInset = shadow.length * -1.0f;
379 const Rect casterWithShadow =
380 Rect(casterRect).inset(shadowInset, shadowInset, shadowInset, shadowInset);
381 const Region shadowRegion = Region(casterWithShadow).subtractSelf(casterRect);
382 const Region backgroundRegion = Region(fullscreenRect()).subtractSelf(casterWithShadow);
383
384 // verify casting layer
385 expectBufferColor(casterRegion, casterColor.r, casterColor.g, casterColor.b, casterColor.a);
386
387 // verify shadows by testing just the alpha since its difficult to validate the shadow color
388 size_t c;
389 Rect const* r = shadowRegion.getArray(&c);
390 for (size_t i = 0; i < c; i++, r++) {
391 expectAlpha(*r, 255);
392 }
393
394 // verify background
395 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
396 backgroundColor.a);
397 }
398
Vishnu Naird9e4f462023-10-06 04:05:45 +0000399 void expectShadowColorWithoutCaster(const FloatRect& casterBounds, const ShadowSettings& shadow,
Alec Mouribd17b3b2020-12-17 11:08:30 -0800400 const ubyte4& backgroundColor) {
401 const float shadowInset = shadow.length * -1.0f;
402 const Rect casterRect(casterBounds);
403 const Rect shadowRect =
404 Rect(casterRect).inset(shadowInset, shadowInset, shadowInset, shadowInset);
405
406 const Region backgroundRegion =
407 Region(fullscreenRect()).subtractSelf(casterRect).subtractSelf(shadowRect);
408
409 expectAlpha(shadowRect, 255);
410 // (0, 0, 0) fill on the bounds of the layer should be ignored.
411 expectBufferColor(casterRect, 255, 255, 255, 255, 254);
412
413 // verify background
414 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
415 backgroundColor.a);
416 }
417
Vishnu Naird9e4f462023-10-06 04:05:45 +0000418 static ShadowSettings getShadowSettings(const vec2& casterPos, float shadowLength,
419 bool casterIsTranslucent) {
420 ShadowSettings shadow;
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800421 shadow.ambientColor = {0.0f, 0.0f, 0.0f, 0.039f};
422 shadow.spotColor = {0.0f, 0.0f, 0.0f, 0.19f};
423 shadow.lightPos = vec3(casterPos.x, casterPos.y, 0);
424 shadow.lightRadius = 0.0f;
425 shadow.length = shadowLength;
426 shadow.casterIsTranslucent = casterIsTranslucent;
427 return shadow;
428 }
429
Alec Mouri1089aed2018-10-25 21:33:57 -0700430 static Rect fullscreenRect() { return Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT); }
431
432 static Rect offsetRect() {
433 return Rect(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_WIDTH,
434 DEFAULT_DISPLAY_HEIGHT);
435 }
436
437 static Rect offsetRectAtZero() {
438 return Rect(DEFAULT_DISPLAY_WIDTH - DEFAULT_DISPLAY_OFFSET,
439 DEFAULT_DISPLAY_HEIGHT - DEFAULT_DISPLAY_OFFSET);
440 }
441
Sally Qi59a9f502021-10-12 18:53:23 +0000442 void invokeDraw(const renderengine::DisplaySettings& settings,
443 const std::vector<renderengine::LayerSettings>& layers) {
Patrick Williams2e9748f2022-08-09 22:48:18 +0000444 ftl::Future<FenceResult> future =
Alec Mourif29700f2023-08-17 21:53:31 +0000445 mRE->drawLayers(settings, layers, mBuffer, base::unique_fd());
Patrick Williams2e9748f2022-08-09 22:48:18 +0000446 ASSERT_TRUE(future.valid());
Sally Qi59a9f502021-10-12 18:53:23 +0000447
Patrick Williams2e9748f2022-08-09 22:48:18 +0000448 auto result = future.get();
449 ASSERT_TRUE(result.ok());
Alec Mouri1089aed2018-10-25 21:33:57 -0700450
Patrick Williams2e9748f2022-08-09 22:48:18 +0000451 auto fence = result.value();
452 fence->waitForever(LOG_TAG);
Alec Mouri1089aed2018-10-25 21:33:57 -0700453 }
454
Alec Mourid43ccab2019-03-13 12:23:45 -0700455 void drawEmptyLayers() {
Alec Mouri6e57f682018-09-29 20:45:08 -0700456 renderengine::DisplaySettings settings;
Sally Qi59a9f502021-10-12 18:53:23 +0000457 std::vector<renderengine::LayerSettings> layers;
Alec Mouric0aae732021-01-12 13:32:18 -0800458 invokeDraw(settings, layers);
Alec Mouri6e57f682018-09-29 20:45:08 -0700459 }
460
Alec Mouri1089aed2018-10-25 21:33:57 -0700461 template <typename SourceVariant>
462 void fillBuffer(half r, half g, half b, half a);
463
464 template <typename SourceVariant>
465 void fillRedBuffer();
466
467 template <typename SourceVariant>
468 void fillGreenBuffer();
469
470 template <typename SourceVariant>
471 void fillBlueBuffer();
472
473 template <typename SourceVariant>
474 void fillRedTransparentBuffer();
475
476 template <typename SourceVariant>
477 void fillRedOffsetBuffer();
478
479 template <typename SourceVariant>
480 void fillBufferPhysicalOffset();
481
482 template <typename SourceVariant>
Alec Mouri5a6d8572020-03-23 23:56:15 -0700483 void fillBufferCheckers(uint32_t rotation);
Alec Mouri1089aed2018-10-25 21:33:57 -0700484
485 template <typename SourceVariant>
486 void fillBufferCheckersRotate0();
487
488 template <typename SourceVariant>
489 void fillBufferCheckersRotate90();
490
491 template <typename SourceVariant>
492 void fillBufferCheckersRotate180();
493
494 template <typename SourceVariant>
495 void fillBufferCheckersRotate270();
496
497 template <typename SourceVariant>
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800498 void fillBufferWithLayerTransform();
499
500 template <typename SourceVariant>
Alec Mouri1089aed2018-10-25 21:33:57 -0700501 void fillBufferLayerTransform();
502
503 template <typename SourceVariant>
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800504 void fillBufferWithColorTransform();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800505
506 template <typename SourceVariant>
Alec Mouri1089aed2018-10-25 21:33:57 -0700507 void fillBufferColorTransform();
508
Alec Mouri7c94edb2018-12-03 21:23:26 -0800509 template <typename SourceVariant>
Sally Qi2019fd22021-11-22 10:19:04 -0800510 void fillBufferWithColorTransformAndSourceDataspace(const ui::Dataspace sourceDataspace);
511
512 template <typename SourceVariant>
513 void fillBufferColorTransformAndSourceDataspace();
514
515 template <typename SourceVariant>
516 void fillBufferWithColorTransformAndOutputDataspace(const ui::Dataspace outputDataspace);
517
518 template <typename SourceVariant>
519 void fillBufferColorTransformAndOutputDataspace();
520
521 template <typename SourceVariant>
KaiChieh Chuangda2845c2020-12-14 16:49:38 +0800522 void fillBufferWithColorTransformZeroLayerAlpha();
523
524 template <typename SourceVariant>
525 void fillBufferColorTransformZeroLayerAlpha();
526
527 template <typename SourceVariant>
Alec Mouri7c94edb2018-12-03 21:23:26 -0800528 void fillRedBufferWithRoundedCorners();
529
530 template <typename SourceVariant>
531 void fillBufferWithRoundedCorners();
532
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000533 template <typename SourceVariant>
Lucas Dupin19c8f0e2019-11-25 17:55:44 -0800534 void fillBufferAndBlurBackground();
535
536 template <typename SourceVariant>
Alec Mourie8489fd2021-04-29 16:08:56 -0700537 void fillSmallLayerAndBlurBackground();
538
539 template <typename SourceVariant>
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000540 void overlayCorners();
541
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800542 void fillRedBufferTextureTransform();
543
544 void fillBufferTextureTransform();
545
546 void fillRedBufferWithPremultiplyAlpha();
547
548 void fillBufferWithPremultiplyAlpha();
549
550 void fillRedBufferWithoutPremultiplyAlpha();
551
552 void fillBufferWithoutPremultiplyAlpha();
553
Alec Mouriac335532018-11-12 15:01:33 -0800554 void fillGreenColorBufferThenClearRegion();
555
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800556 template <typename SourceVariant>
Vishnu Naird9e4f462023-10-06 04:05:45 +0000557 void drawShadow(const renderengine::LayerSettings& castingLayer, const ShadowSettings& shadow,
558 const ubyte4& casterColor, const ubyte4& backgroundColor);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800559
Vishnu Naird9e4f462023-10-06 04:05:45 +0000560 void drawShadowWithoutCaster(const FloatRect& castingBounds, const ShadowSettings& shadow,
Alec Mouribd17b3b2020-12-17 11:08:30 -0800561 const ubyte4& backgroundColor);
562
Alec Mouri5a493722022-01-26 16:43:02 -0800563 // Tonemaps grey values from sourceDataspace -> Display P3 and checks that GPU and CPU
564 // implementations are identical Also implicitly checks that the injected tonemap shader
565 // compiles
566 void tonemap(ui::Dataspace sourceDataspace, std::function<vec3(vec3)> eotf,
567 std::function<vec3(vec3, float)> scaleOotf);
568
Alec Mouric0aae732021-01-12 13:32:18 -0800569 void initializeRenderEngine();
570
571 std::unique_ptr<renderengine::RenderEngine> mRE;
Alec Mouria90a5702021-04-16 16:36:21 +0000572 std::shared_ptr<renderengine::ExternalTexture> mBuffer;
Alec Mouri6e57f682018-09-29 20:45:08 -0700573};
574
Alec Mouric0aae732021-01-12 13:32:18 -0800575void RenderEngineTest::initializeRenderEngine() {
576 const auto& renderEngineFactory = GetParam();
Alec Mouric16974e2022-09-13 17:35:48 +0000577 mRE = renderEngineFactory->createRenderEngine();
Alec Mouria90a5702021-04-16 16:36:21 +0000578 mBuffer = allocateDefaultBuffer();
Alec Mouric0aae732021-01-12 13:32:18 -0800579}
580
Alec Mouri1089aed2018-10-25 21:33:57 -0700581struct ColorSourceVariant {
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800582 static void fillColor(renderengine::LayerSettings& layer, half r, half g, half b,
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800583 RenderEngineTest* /*fixture*/) {
Alec Mouri1089aed2018-10-25 21:33:57 -0700584 layer.source.solidColor = half3(r, g, b);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800585 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700586 }
587};
588
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800589struct RelaxOpaqueBufferVariant {
590 static void setOpaqueBit(renderengine::LayerSettings& layer) {
591 layer.source.buffer.isOpaque = false;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800592 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800593 }
594
595 static uint8_t getAlphaChannel() { return 255; }
596};
597
598struct ForceOpaqueBufferVariant {
599 static void setOpaqueBit(renderengine::LayerSettings& layer) {
600 layer.source.buffer.isOpaque = true;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800601 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800602 }
603
604 static uint8_t getAlphaChannel() {
605 // The isOpaque bit will override the alpha channel, so this should be
606 // arbitrary.
Alec Mouric0aae732021-01-12 13:32:18 -0800607 return 50;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800608 }
609};
610
611template <typename OpaquenessVariant>
612struct BufferSourceVariant {
613 static void fillColor(renderengine::LayerSettings& layer, half r, half g, half b,
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800614 RenderEngineTest* fixture) {
Alec Mouria90a5702021-04-16 16:36:21 +0000615 const auto buf = fixture->allocateSourceBuffer(1, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800616
617 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +0000618 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
619 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800620
Alec Mouria90a5702021-04-16 16:36:21 +0000621 for (int32_t j = 0; j < buf->getBuffer()->getHeight(); j++) {
622 uint8_t* iter = pixels + (buf->getBuffer()->getStride() * j) * 4;
623 for (int32_t i = 0; i < buf->getBuffer()->getWidth(); i++) {
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800624 iter[0] = uint8_t(r * 255);
625 iter[1] = uint8_t(g * 255);
626 iter[2] = uint8_t(b * 255);
627 iter[3] = OpaquenessVariant::getAlphaChannel();
628 iter += 4;
629 }
630 }
631
Alec Mouria90a5702021-04-16 16:36:21 +0000632 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800633
634 layer.source.buffer.buffer = buf;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800635 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800636 OpaquenessVariant::setOpaqueBit(layer);
637 }
638};
639
Alec Mouri1089aed2018-10-25 21:33:57 -0700640template <typename SourceVariant>
641void RenderEngineTest::fillBuffer(half r, half g, half b, half a) {
642 renderengine::DisplaySettings settings;
643 settings.physicalDisplay = fullscreenRect();
644 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800645 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700646
Sally Qi59a9f502021-10-12 18:53:23 +0000647 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700648
649 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800650 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700651 layer.geometry.boundaries = fullscreenRect().toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800652 SourceVariant::fillColor(layer, r, g, b, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700653 layer.alpha = a;
654
Sally Qi59a9f502021-10-12 18:53:23 +0000655 layers.push_back(layer);
Alec Mouri1089aed2018-10-25 21:33:57 -0700656
Alec Mouric0aae732021-01-12 13:32:18 -0800657 invokeDraw(settings, layers);
Alec Mouri1089aed2018-10-25 21:33:57 -0700658}
659
660template <typename SourceVariant>
661void RenderEngineTest::fillRedBuffer() {
662 fillBuffer<SourceVariant>(1.0f, 0.0f, 0.0f, 1.0f);
663 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
664}
665
666template <typename SourceVariant>
667void RenderEngineTest::fillGreenBuffer() {
668 fillBuffer<SourceVariant>(0.0f, 1.0f, 0.0f, 1.0f);
669 expectBufferColor(fullscreenRect(), 0, 255, 0, 255);
670}
671
672template <typename SourceVariant>
673void RenderEngineTest::fillBlueBuffer() {
674 fillBuffer<SourceVariant>(0.0f, 0.0f, 1.0f, 1.0f);
675 expectBufferColor(fullscreenRect(), 0, 0, 255, 255);
676}
677
678template <typename SourceVariant>
679void RenderEngineTest::fillRedTransparentBuffer() {
680 fillBuffer<SourceVariant>(1.0f, 0.0f, 0.0f, .2f);
681 expectBufferColor(fullscreenRect(), 51, 0, 0, 51);
682}
683
684template <typename SourceVariant>
685void RenderEngineTest::fillRedOffsetBuffer() {
686 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800687 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700688 settings.physicalDisplay = offsetRect();
689 settings.clip = offsetRectAtZero();
690
Sally Qi59a9f502021-10-12 18:53:23 +0000691 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700692
693 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800694 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700695 layer.geometry.boundaries = offsetRectAtZero().toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800696 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700697 layer.alpha = 1.0f;
698
Sally Qi59a9f502021-10-12 18:53:23 +0000699 layers.push_back(layer);
Alec Mouric0aae732021-01-12 13:32:18 -0800700 invokeDraw(settings, layers);
Alec Mouri1089aed2018-10-25 21:33:57 -0700701}
702
703template <typename SourceVariant>
704void RenderEngineTest::fillBufferPhysicalOffset() {
705 fillRedOffsetBuffer<SourceVariant>();
706
707 expectBufferColor(Rect(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_WIDTH,
708 DEFAULT_DISPLAY_HEIGHT),
709 255, 0, 0, 255);
710 Rect offsetRegionLeft(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_HEIGHT);
711 Rect offsetRegionTop(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_OFFSET);
712
713 expectBufferColor(offsetRegionLeft, 0, 0, 0, 0);
714 expectBufferColor(offsetRegionTop, 0, 0, 0, 0);
715}
716
717template <typename SourceVariant>
Alec Mouri5a6d8572020-03-23 23:56:15 -0700718void RenderEngineTest::fillBufferCheckers(uint32_t orientationFlag) {
Alec Mouri1089aed2018-10-25 21:33:57 -0700719 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800720 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700721 settings.physicalDisplay = fullscreenRect();
722 // Here logical space is 2x2
723 settings.clip = Rect(2, 2);
Alec Mouri5a6d8572020-03-23 23:56:15 -0700724 settings.orientation = orientationFlag;
Alec Mouri1089aed2018-10-25 21:33:57 -0700725
Sally Qi59a9f502021-10-12 18:53:23 +0000726 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700727
728 renderengine::LayerSettings layerOne;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800729 layerOne.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700730 Rect rectOne(0, 0, 1, 1);
731 layerOne.geometry.boundaries = rectOne.toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800732 SourceVariant::fillColor(layerOne, 1.0f, 0.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700733 layerOne.alpha = 1.0f;
734
735 renderengine::LayerSettings layerTwo;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800736 layerTwo.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700737 Rect rectTwo(0, 1, 1, 2);
738 layerTwo.geometry.boundaries = rectTwo.toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800739 SourceVariant::fillColor(layerTwo, 0.0f, 1.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700740 layerTwo.alpha = 1.0f;
741
742 renderengine::LayerSettings layerThree;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800743 layerThree.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700744 Rect rectThree(1, 0, 2, 1);
745 layerThree.geometry.boundaries = rectThree.toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800746 SourceVariant::fillColor(layerThree, 0.0f, 0.0f, 1.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700747 layerThree.alpha = 1.0f;
748
Sally Qi59a9f502021-10-12 18:53:23 +0000749 layers.push_back(layerOne);
750 layers.push_back(layerTwo);
751 layers.push_back(layerThree);
Alec Mouri1089aed2018-10-25 21:33:57 -0700752
Alec Mouric0aae732021-01-12 13:32:18 -0800753 invokeDraw(settings, layers);
Alec Mouri1089aed2018-10-25 21:33:57 -0700754}
755
756template <typename SourceVariant>
757void RenderEngineTest::fillBufferCheckersRotate0() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700758 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_0);
Alec Mouri1089aed2018-10-25 21:33:57 -0700759 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0,
760 255);
761 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
762 DEFAULT_DISPLAY_HEIGHT / 2),
763 0, 0, 255, 255);
764 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
765 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
766 0, 0, 0, 0);
767 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
768 DEFAULT_DISPLAY_HEIGHT),
769 0, 255, 0, 255);
770}
771
772template <typename SourceVariant>
773void RenderEngineTest::fillBufferCheckersRotate90() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700774 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_90);
Alec Mouri1089aed2018-10-25 21:33:57 -0700775 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 255, 0,
776 255);
777 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
778 DEFAULT_DISPLAY_HEIGHT / 2),
779 255, 0, 0, 255);
780 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
781 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
782 0, 0, 255, 255);
783 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
784 DEFAULT_DISPLAY_HEIGHT),
785 0, 0, 0, 0);
786}
787
788template <typename SourceVariant>
789void RenderEngineTest::fillBufferCheckersRotate180() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700790 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_180);
Alec Mouri1089aed2018-10-25 21:33:57 -0700791 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 0,
792 0);
793 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
794 DEFAULT_DISPLAY_HEIGHT / 2),
795 0, 255, 0, 255);
796 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
797 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
798 255, 0, 0, 255);
799 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
800 DEFAULT_DISPLAY_HEIGHT),
801 0, 0, 255, 255);
802}
803
804template <typename SourceVariant>
805void RenderEngineTest::fillBufferCheckersRotate270() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700806 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_270);
Alec Mouri1089aed2018-10-25 21:33:57 -0700807 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 255,
808 255);
809 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
810 DEFAULT_DISPLAY_HEIGHT / 2),
811 0, 0, 0, 0);
812 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
813 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
814 0, 255, 0, 255);
815 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
816 DEFAULT_DISPLAY_HEIGHT),
817 255, 0, 0, 255);
818}
819
820template <typename SourceVariant>
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800821void RenderEngineTest::fillBufferWithLayerTransform() {
Alec Mouri1089aed2018-10-25 21:33:57 -0700822 renderengine::DisplaySettings settings;
823 settings.physicalDisplay = fullscreenRect();
824 // Here logical space is 2x2
825 settings.clip = Rect(2, 2);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800826 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700827
Sally Qi59a9f502021-10-12 18:53:23 +0000828 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700829
830 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800831 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700832 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
833 // Translate one pixel diagonally
834 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 -0800835 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700836 layer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
837 layer.alpha = 1.0f;
838
Sally Qi59a9f502021-10-12 18:53:23 +0000839 layers.push_back(layer);
Alec Mouri1089aed2018-10-25 21:33:57 -0700840
Alec Mouric0aae732021-01-12 13:32:18 -0800841 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800842}
Alec Mouri1089aed2018-10-25 21:33:57 -0700843
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800844template <typename SourceVariant>
845void RenderEngineTest::fillBufferLayerTransform() {
846 fillBufferWithLayerTransform<SourceVariant>();
Alec Mouri1089aed2018-10-25 21:33:57 -0700847 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 0, 0);
848 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
849 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
850 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
851 255, 0, 0, 255);
852}
853
854template <typename SourceVariant>
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800855void RenderEngineTest::fillBufferWithColorTransform() {
Alec Mouri1089aed2018-10-25 21:33:57 -0700856 renderengine::DisplaySettings settings;
857 settings.physicalDisplay = fullscreenRect();
858 settings.clip = Rect(1, 1);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800859 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700860
Sally Qi59a9f502021-10-12 18:53:23 +0000861 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700862
863 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800864 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700865 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800866 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700867 layer.alpha = 1.0f;
868
869 // construct a fake color matrix
870 // annihilate green and blue channels
KaiChieh Chuang436fc192020-09-07 13:48:42 +0800871 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
Alec Mouri1089aed2018-10-25 21:33:57 -0700872 // set red channel to red + green
873 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
874
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800875 layer.alpha = 1.0f;
876 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
877
Sally Qi59a9f502021-10-12 18:53:23 +0000878 layers.push_back(layer);
Alec Mouri1089aed2018-10-25 21:33:57 -0700879
Alec Mouric0aae732021-01-12 13:32:18 -0800880 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800881}
Alec Mouri1089aed2018-10-25 21:33:57 -0700882
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800883template <typename SourceVariant>
Sally Qi2019fd22021-11-22 10:19:04 -0800884void RenderEngineTest::fillBufferWithColorTransformAndSourceDataspace(
885 const ui::Dataspace sourceDataspace) {
886 renderengine::DisplaySettings settings;
887 settings.physicalDisplay = fullscreenRect();
888 settings.clip = Rect(1, 1);
889 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
890
891 std::vector<renderengine::LayerSettings> layers;
892
893 renderengine::LayerSettings layer;
Sally Qi2019fd22021-11-22 10:19:04 -0800894 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
895 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
Alec Mouric16974e2022-09-13 17:35:48 +0000896 layer.sourceDataspace = sourceDataspace;
Sally Qi2019fd22021-11-22 10:19:04 -0800897 layer.alpha = 1.0f;
898
899 // construct a fake color matrix
900 // annihilate green and blue channels
901 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
902 // set red channel to red + green
903 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
904
905 layer.alpha = 1.0f;
906 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
907
908 layers.push_back(layer);
909
910 invokeDraw(settings, layers);
911}
912
913template <typename SourceVariant>
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800914void RenderEngineTest::fillBufferColorTransform() {
915 fillBufferWithColorTransform<SourceVariant>();
KaiChieh Chuang436fc192020-09-07 13:48:42 +0800916 expectBufferColor(fullscreenRect(), 172, 0, 0, 255, 1);
917}
918
919template <typename SourceVariant>
Sally Qi2019fd22021-11-22 10:19:04 -0800920void RenderEngineTest::fillBufferColorTransformAndSourceDataspace() {
921 unordered_map<ui::Dataspace, ubyte4> dataspaceToColorMap;
Alec Mouric16974e2022-09-13 17:35:48 +0000922 dataspaceToColorMap[ui::Dataspace::V0_BT709] = {77, 0, 0, 255};
923 dataspaceToColorMap[ui::Dataspace::BT2020] = {101, 0, 0, 255};
924 dataspaceToColorMap[ui::Dataspace::ADOBE_RGB] = {75, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -0800925 ui::Dataspace customizedDataspace = static_cast<ui::Dataspace>(
926 ui::Dataspace::STANDARD_BT709 | ui::Dataspace::TRANSFER_GAMMA2_2 |
927 ui::Dataspace::RANGE_FULL);
Alec Mouric16974e2022-09-13 17:35:48 +0000928 dataspaceToColorMap[customizedDataspace] = {61, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -0800929 for (const auto& [sourceDataspace, color] : dataspaceToColorMap) {
930 fillBufferWithColorTransformAndSourceDataspace<SourceVariant>(sourceDataspace);
931 expectBufferColor(fullscreenRect(), color.r, color.g, color.b, color.a, 1);
932 }
933}
934
935template <typename SourceVariant>
936void RenderEngineTest::fillBufferWithColorTransformAndOutputDataspace(
937 const ui::Dataspace outputDataspace) {
938 renderengine::DisplaySettings settings;
939 settings.physicalDisplay = fullscreenRect();
940 settings.clip = Rect(1, 1);
941 settings.outputDataspace = outputDataspace;
942
943 std::vector<renderengine::LayerSettings> layers;
944
945 renderengine::LayerSettings layer;
946 layer.sourceDataspace = ui::Dataspace::V0_SCRGB_LINEAR;
947 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
948 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
949 layer.alpha = 1.0f;
950
951 // construct a fake color matrix
952 // annihilate green and blue channels
953 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
954 // set red channel to red + green
955 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
956
957 layer.alpha = 1.0f;
958 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
959
960 layers.push_back(layer);
961
962 invokeDraw(settings, layers);
963}
964
965template <typename SourceVariant>
966void RenderEngineTest::fillBufferColorTransformAndOutputDataspace() {
967 unordered_map<ui::Dataspace, ubyte4> dataspaceToColorMap;
Alec Mouric16974e2022-09-13 17:35:48 +0000968 dataspaceToColorMap[ui::Dataspace::V0_BT709] = {198, 0, 0, 255};
969 dataspaceToColorMap[ui::Dataspace::BT2020] = {187, 0, 0, 255};
970 dataspaceToColorMap[ui::Dataspace::ADOBE_RGB] = {192, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -0800971 ui::Dataspace customizedDataspace = static_cast<ui::Dataspace>(
972 ui::Dataspace::STANDARD_BT709 | ui::Dataspace::TRANSFER_GAMMA2_6 |
973 ui::Dataspace::RANGE_FULL);
Alec Mouric16974e2022-09-13 17:35:48 +0000974 dataspaceToColorMap[customizedDataspace] = {205, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -0800975 for (const auto& [outputDataspace, color] : dataspaceToColorMap) {
976 fillBufferWithColorTransformAndOutputDataspace<SourceVariant>(outputDataspace);
977 expectBufferColor(fullscreenRect(), color.r, color.g, color.b, color.a, 1);
978 }
979}
980
981template <typename SourceVariant>
KaiChieh Chuangda2845c2020-12-14 16:49:38 +0800982void RenderEngineTest::fillBufferWithColorTransformZeroLayerAlpha() {
983 renderengine::DisplaySettings settings;
984 settings.physicalDisplay = fullscreenRect();
985 settings.clip = Rect(1, 1);
986
Sally Qi59a9f502021-10-12 18:53:23 +0000987 std::vector<renderengine::LayerSettings> layers;
KaiChieh Chuangda2845c2020-12-14 16:49:38 +0800988
989 renderengine::LayerSettings layer;
990 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
991 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
992 layer.alpha = 0;
993
994 // construct a fake color matrix
995 // simple inverse color
996 settings.colorTransform = mat4(-1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 1, 1, 1, 1);
997
998 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
999
Sally Qi59a9f502021-10-12 18:53:23 +00001000 layers.push_back(layer);
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001001
Alec Mouric0aae732021-01-12 13:32:18 -08001002 invokeDraw(settings, layers);
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001003}
1004
1005template <typename SourceVariant>
1006void RenderEngineTest::fillBufferColorTransformZeroLayerAlpha() {
1007 fillBufferWithColorTransformZeroLayerAlpha<SourceVariant>();
1008 expectBufferColor(fullscreenRect(), 0, 0, 0, 0);
1009}
1010
1011template <typename SourceVariant>
Alec Mouri7c94edb2018-12-03 21:23:26 -08001012void RenderEngineTest::fillRedBufferWithRoundedCorners() {
1013 renderengine::DisplaySettings settings;
1014 settings.physicalDisplay = fullscreenRect();
1015 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001016 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri7c94edb2018-12-03 21:23:26 -08001017
Sally Qi59a9f502021-10-12 18:53:23 +00001018 std::vector<renderengine::LayerSettings> layers;
Alec Mouri7c94edb2018-12-03 21:23:26 -08001019
1020 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001021 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri7c94edb2018-12-03 21:23:26 -08001022 layer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07001023 layer.geometry.roundedCornersRadius = {5.0f, 5.0f};
Alec Mouri7c94edb2018-12-03 21:23:26 -08001024 layer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
1025 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
1026 layer.alpha = 1.0f;
1027
Sally Qi59a9f502021-10-12 18:53:23 +00001028 layers.push_back(layer);
Alec Mouri7c94edb2018-12-03 21:23:26 -08001029
Alec Mouric0aae732021-01-12 13:32:18 -08001030 invokeDraw(settings, layers);
Alec Mouri7c94edb2018-12-03 21:23:26 -08001031}
1032
1033template <typename SourceVariant>
1034void RenderEngineTest::fillBufferWithRoundedCorners() {
1035 fillRedBufferWithRoundedCorners<SourceVariant>();
1036 // Corners should be ignored...
1037 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 0);
1038 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, 0, DEFAULT_DISPLAY_WIDTH, 1), 0, 0, 0, 0);
1039 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT - 1, 1, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
1040 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1,
1041 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1042 0, 0, 0, 0);
1043 // ...And the non-rounded portion should be red.
1044 // Other pixels may be anti-aliased, so let's not check those.
1045 expectBufferColor(Rect(5, 5, DEFAULT_DISPLAY_WIDTH - 5, DEFAULT_DISPLAY_HEIGHT - 5), 255, 0, 0,
1046 255);
1047}
1048
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001049template <typename SourceVariant>
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001050void RenderEngineTest::fillBufferAndBlurBackground() {
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001051 auto blurRadius = 50;
1052 auto center = DEFAULT_DISPLAY_WIDTH / 2;
1053
1054 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001055 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001056 settings.physicalDisplay = fullscreenRect();
1057 settings.clip = fullscreenRect();
1058
Sally Qi59a9f502021-10-12 18:53:23 +00001059 std::vector<renderengine::LayerSettings> layers;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001060
1061 renderengine::LayerSettings backgroundLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001062 backgroundLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001063 backgroundLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1064 SourceVariant::fillColor(backgroundLayer, 0.0f, 1.0f, 0.0f, this);
1065 backgroundLayer.alpha = 1.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001066 layers.emplace_back(backgroundLayer);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001067
1068 renderengine::LayerSettings leftLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001069 leftLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001070 leftLayer.geometry.boundaries =
1071 Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT).toFloatRect();
1072 SourceVariant::fillColor(leftLayer, 1.0f, 0.0f, 0.0f, this);
1073 leftLayer.alpha = 1.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001074 layers.emplace_back(leftLayer);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001075
1076 renderengine::LayerSettings blurLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001077 blurLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001078 blurLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1079 blurLayer.backgroundBlurRadius = blurRadius;
Derek Sollenbergerecb21462021-01-29 16:53:49 -05001080 SourceVariant::fillColor(blurLayer, 0.0f, 0.0f, 1.0f, this);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001081 blurLayer.alpha = 0;
Sally Qi59a9f502021-10-12 18:53:23 +00001082 layers.emplace_back(blurLayer);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001083
Alec Mouric0aae732021-01-12 13:32:18 -08001084 invokeDraw(settings, layers);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001085
Derek Sollenbergerecb21462021-01-29 16:53:49 -05001086 // solid color
1087 expectBufferColor(Rect(0, 0, 1, 1), 255, 0, 0, 255, 0 /* tolerance */);
1088
Derek Sollenbergerb3998372021-02-16 15:16:56 -05001089 if (mRE->supportsBackgroundBlur()) {
1090 // blurred color (downsampling should result in the center color being close to 128)
1091 expectBufferColor(Rect(center - 1, center - 5, center + 1, center + 5), 128, 128, 0, 255,
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001092 50 /* tolerance */);
Derek Sollenbergerb3998372021-02-16 15:16:56 -05001093 }
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001094}
1095
1096template <typename SourceVariant>
Alec Mourie8489fd2021-04-29 16:08:56 -07001097void RenderEngineTest::fillSmallLayerAndBlurBackground() {
1098 auto blurRadius = 50;
1099 renderengine::DisplaySettings settings;
1100 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1101 settings.physicalDisplay = fullscreenRect();
1102 settings.clip = fullscreenRect();
1103
Sally Qi59a9f502021-10-12 18:53:23 +00001104 std::vector<renderengine::LayerSettings> layers;
Alec Mourie8489fd2021-04-29 16:08:56 -07001105
1106 renderengine::LayerSettings backgroundLayer;
1107 backgroundLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1108 backgroundLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1109 SourceVariant::fillColor(backgroundLayer, 1.0f, 0.0f, 0.0f, this);
1110 backgroundLayer.alpha = 1.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001111 layers.push_back(backgroundLayer);
Alec Mourie8489fd2021-04-29 16:08:56 -07001112
1113 renderengine::LayerSettings blurLayer;
1114 blurLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1115 blurLayer.geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f);
1116 blurLayer.backgroundBlurRadius = blurRadius;
1117 SourceVariant::fillColor(blurLayer, 0.0f, 0.0f, 1.0f, this);
1118 blurLayer.alpha = 0;
Sally Qi59a9f502021-10-12 18:53:23 +00001119 layers.push_back(blurLayer);
Alec Mourie8489fd2021-04-29 16:08:56 -07001120
1121 invokeDraw(settings, layers);
1122
1123 // Give a generous tolerance - the blur rectangle is very small and this test is
1124 // mainly concerned with ensuring that there's no device failure.
1125 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT), 255, 0, 0, 255,
1126 40 /* tolerance */);
1127}
1128
1129template <typename SourceVariant>
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001130void RenderEngineTest::overlayCorners() {
1131 renderengine::DisplaySettings settings;
1132 settings.physicalDisplay = fullscreenRect();
1133 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001134 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001135
Sally Qi59a9f502021-10-12 18:53:23 +00001136 std::vector<renderengine::LayerSettings> layersFirst;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001137
1138 renderengine::LayerSettings layerOne;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001139 layerOne.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001140 layerOne.geometry.boundaries =
1141 FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH / 3.0, DEFAULT_DISPLAY_HEIGHT / 3.0);
1142 SourceVariant::fillColor(layerOne, 1.0f, 0.0f, 0.0f, this);
1143 layerOne.alpha = 0.2;
1144
Sally Qi59a9f502021-10-12 18:53:23 +00001145 layersFirst.push_back(layerOne);
Alec Mouric0aae732021-01-12 13:32:18 -08001146 invokeDraw(settings, layersFirst);
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001147 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3), 51, 0, 0, 51);
1148 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3 + 1, DEFAULT_DISPLAY_HEIGHT / 3 + 1,
1149 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1150 0, 0, 0, 0);
1151
Sally Qi59a9f502021-10-12 18:53:23 +00001152 std::vector<renderengine::LayerSettings> layersSecond;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001153 renderengine::LayerSettings layerTwo;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001154 layerTwo.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001155 layerTwo.geometry.boundaries =
1156 FloatRect(DEFAULT_DISPLAY_WIDTH / 3.0, DEFAULT_DISPLAY_HEIGHT / 3.0,
1157 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT);
1158 SourceVariant::fillColor(layerTwo, 0.0f, 1.0f, 0.0f, this);
1159 layerTwo.alpha = 1.0f;
1160
Sally Qi59a9f502021-10-12 18:53:23 +00001161 layersSecond.push_back(layerTwo);
Alec Mouric0aae732021-01-12 13:32:18 -08001162 invokeDraw(settings, layersSecond);
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001163
1164 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3), 0, 0, 0, 0);
1165 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3 + 1, DEFAULT_DISPLAY_HEIGHT / 3 + 1,
1166 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1167 0, 255, 0, 255);
1168}
1169
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001170void RenderEngineTest::fillRedBufferTextureTransform() {
1171 renderengine::DisplaySettings settings;
1172 settings.physicalDisplay = fullscreenRect();
1173 settings.clip = Rect(1, 1);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001174 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001175
Sally Qi59a9f502021-10-12 18:53:23 +00001176 std::vector<renderengine::LayerSettings> layers;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001177
1178 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001179 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001180 // Here will allocate a checker board texture, but transform texture
1181 // coordinates so that only the upper left is applied.
Alec Mouria90a5702021-04-16 16:36:21 +00001182 const auto buf = allocateSourceBuffer(2, 2);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001183
1184 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00001185 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1186 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001187 // Red top left, Green top right, Blue bottom left, Black bottom right
1188 pixels[0] = 255;
1189 pixels[1] = 0;
1190 pixels[2] = 0;
1191 pixels[3] = 255;
1192 pixels[4] = 0;
1193 pixels[5] = 255;
1194 pixels[6] = 0;
1195 pixels[7] = 255;
1196 pixels[8] = 0;
1197 pixels[9] = 0;
1198 pixels[10] = 255;
1199 pixels[11] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00001200 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001201
1202 layer.source.buffer.buffer = buf;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001203 // Transform coordinates to only be inside the red quadrant.
Alec Mouri4049b532021-10-15 20:59:33 -07001204 layer.source.buffer.textureTransform = mat4::scale(vec4(0.2f, 0.2f, 1.f, 1.f));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001205 layer.alpha = 1.0f;
1206 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1207
Sally Qi59a9f502021-10-12 18:53:23 +00001208 layers.push_back(layer);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001209
Alec Mouric0aae732021-01-12 13:32:18 -08001210 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001211}
1212
1213void RenderEngineTest::fillBufferTextureTransform() {
1214 fillRedBufferTextureTransform();
1215 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
1216}
1217
1218void RenderEngineTest::fillRedBufferWithPremultiplyAlpha() {
1219 renderengine::DisplaySettings settings;
1220 settings.physicalDisplay = fullscreenRect();
1221 // Here logical space is 1x1
1222 settings.clip = Rect(1, 1);
1223
Sally Qi59a9f502021-10-12 18:53:23 +00001224 std::vector<renderengine::LayerSettings> layers;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001225
1226 renderengine::LayerSettings layer;
Alec Mouria90a5702021-04-16 16:36:21 +00001227 const auto buf = allocateSourceBuffer(1, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001228
1229 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00001230 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1231 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001232 pixels[0] = 255;
1233 pixels[1] = 0;
1234 pixels[2] = 0;
1235 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00001236 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001237
1238 layer.source.buffer.buffer = buf;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001239 layer.source.buffer.usePremultipliedAlpha = true;
1240 layer.alpha = 0.5f;
1241 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1242
Sally Qi59a9f502021-10-12 18:53:23 +00001243 layers.push_back(layer);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001244
Alec Mouric0aae732021-01-12 13:32:18 -08001245 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001246}
1247
1248void RenderEngineTest::fillBufferWithPremultiplyAlpha() {
1249 fillRedBufferWithPremultiplyAlpha();
1250 expectBufferColor(fullscreenRect(), 128, 0, 0, 128);
1251}
1252
1253void RenderEngineTest::fillRedBufferWithoutPremultiplyAlpha() {
1254 renderengine::DisplaySettings settings;
1255 settings.physicalDisplay = fullscreenRect();
1256 // Here logical space is 1x1
1257 settings.clip = Rect(1, 1);
1258
Sally Qi59a9f502021-10-12 18:53:23 +00001259 std::vector<renderengine::LayerSettings> layers;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001260
1261 renderengine::LayerSettings layer;
Alec Mouria90a5702021-04-16 16:36:21 +00001262 const auto buf = allocateSourceBuffer(1, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001263
1264 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00001265 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1266 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001267 pixels[0] = 255;
1268 pixels[1] = 0;
1269 pixels[2] = 0;
1270 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00001271 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001272
1273 layer.source.buffer.buffer = buf;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001274 layer.source.buffer.usePremultipliedAlpha = false;
1275 layer.alpha = 0.5f;
1276 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1277
Sally Qi59a9f502021-10-12 18:53:23 +00001278 layers.push_back(layer);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001279
Alec Mouric0aae732021-01-12 13:32:18 -08001280 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001281}
1282
1283void RenderEngineTest::fillBufferWithoutPremultiplyAlpha() {
1284 fillRedBufferWithoutPremultiplyAlpha();
wukui16f3c0bb2020-08-05 20:35:29 +08001285 expectBufferColor(fullscreenRect(), 128, 0, 0, 128, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001286}
1287
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001288template <typename SourceVariant>
1289void RenderEngineTest::drawShadow(const renderengine::LayerSettings& castingLayer,
Vishnu Naird9e4f462023-10-06 04:05:45 +00001290 const ShadowSettings& shadow, const ubyte4& casterColor,
1291 const ubyte4& backgroundColor) {
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001292 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001293 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001294 settings.physicalDisplay = fullscreenRect();
1295 settings.clip = fullscreenRect();
1296
Sally Qi59a9f502021-10-12 18:53:23 +00001297 std::vector<renderengine::LayerSettings> layers;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001298
1299 // add background layer
1300 renderengine::LayerSettings bgLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001301 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001302 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1303 ColorSourceVariant::fillColor(bgLayer, backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1304 backgroundColor.b / 255.0f, this);
1305 bgLayer.alpha = backgroundColor.a / 255.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001306 layers.push_back(bgLayer);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001307
1308 // add shadow layer
1309 renderengine::LayerSettings shadowLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001310 shadowLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001311 shadowLayer.geometry.boundaries = castingLayer.geometry.boundaries;
1312 shadowLayer.alpha = castingLayer.alpha;
1313 shadowLayer.shadow = shadow;
Sally Qi59a9f502021-10-12 18:53:23 +00001314 layers.push_back(shadowLayer);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001315
1316 // add layer casting the shadow
1317 renderengine::LayerSettings layer = castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001318 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001319 SourceVariant::fillColor(layer, casterColor.r / 255.0f, casterColor.g / 255.0f,
1320 casterColor.b / 255.0f, this);
Sally Qi59a9f502021-10-12 18:53:23 +00001321 layers.push_back(layer);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001322
Alec Mouric0aae732021-01-12 13:32:18 -08001323 invokeDraw(settings, layers);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001324}
1325
Alec Mouribd17b3b2020-12-17 11:08:30 -08001326void RenderEngineTest::drawShadowWithoutCaster(const FloatRect& castingBounds,
Vishnu Naird9e4f462023-10-06 04:05:45 +00001327 const ShadowSettings& shadow,
Alec Mouribd17b3b2020-12-17 11:08:30 -08001328 const ubyte4& backgroundColor) {
1329 renderengine::DisplaySettings settings;
1330 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1331 settings.physicalDisplay = fullscreenRect();
1332 settings.clip = fullscreenRect();
1333
Sally Qi59a9f502021-10-12 18:53:23 +00001334 std::vector<renderengine::LayerSettings> layers;
Alec Mouribd17b3b2020-12-17 11:08:30 -08001335
1336 // add background layer
1337 renderengine::LayerSettings bgLayer;
1338 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1339 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1340 ColorSourceVariant::fillColor(bgLayer, backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1341 backgroundColor.b / 255.0f, this);
1342 bgLayer.alpha = backgroundColor.a / 255.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001343 layers.push_back(bgLayer);
Alec Mouribd17b3b2020-12-17 11:08:30 -08001344
1345 // add shadow layer
1346 renderengine::LayerSettings shadowLayer;
1347 shadowLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1348 shadowLayer.geometry.boundaries = castingBounds;
Derek Sollenbergerc31985e2021-05-18 16:38:17 -04001349 shadowLayer.skipContentDraw = true;
Alec Mouribd17b3b2020-12-17 11:08:30 -08001350 shadowLayer.alpha = 1.0f;
1351 ColorSourceVariant::fillColor(shadowLayer, 0, 0, 0, this);
1352 shadowLayer.shadow = shadow;
Sally Qi59a9f502021-10-12 18:53:23 +00001353 layers.push_back(shadowLayer);
Alec Mouribd17b3b2020-12-17 11:08:30 -08001354
Alec Mouric0aae732021-01-12 13:32:18 -08001355 invokeDraw(settings, layers);
Alec Mouribd17b3b2020-12-17 11:08:30 -08001356}
1357
Alec Mouri5a493722022-01-26 16:43:02 -08001358void RenderEngineTest::tonemap(ui::Dataspace sourceDataspace, std::function<vec3(vec3)> eotf,
1359 std::function<vec3(vec3, float)> scaleOotf) {
1360 constexpr int32_t kGreyLevels = 256;
1361
1362 const auto rect = Rect(0, 0, kGreyLevels, 1);
1363
1364 constexpr float kMaxLuminance = 750.f;
1365 constexpr float kCurrentLuminanceNits = 500.f;
1366 const renderengine::DisplaySettings display{
1367 .physicalDisplay = rect,
1368 .clip = rect,
1369 .maxLuminance = kMaxLuminance,
1370 .currentLuminanceNits = kCurrentLuminanceNits,
1371 .outputDataspace = ui::Dataspace::DISPLAY_P3,
1372 };
1373
1374 auto buf = std::make_shared<
1375 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07001376 ExternalTexture>(sp<GraphicBuffer>::make(kGreyLevels, 1,
1377 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1378 GRALLOC_USAGE_SW_READ_OFTEN |
1379 GRALLOC_USAGE_SW_WRITE_OFTEN |
1380 GRALLOC_USAGE_HW_RENDER |
1381 GRALLOC_USAGE_HW_TEXTURE,
1382 "input"),
Alec Mouri5a493722022-01-26 16:43:02 -08001383 *mRE,
1384 renderengine::impl::ExternalTexture::Usage::READABLE |
1385 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
1386 ASSERT_EQ(0, buf->getBuffer()->initCheck());
1387 {
1388 uint8_t* pixels;
1389 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1390 reinterpret_cast<void**>(&pixels));
1391
1392 uint8_t color = 0;
1393 for (int32_t j = 0; j < buf->getBuffer()->getHeight(); j++) {
1394 uint8_t* dest = pixels + (buf->getBuffer()->getStride() * j * 4);
1395 for (int32_t i = 0; i < buf->getBuffer()->getWidth(); i++) {
1396 dest[0] = color;
1397 dest[1] = color;
1398 dest[2] = color;
1399 dest[3] = 255;
1400 color++;
1401 dest += 4;
1402 }
1403 }
1404 buf->getBuffer()->unlock();
1405 }
1406
1407 mBuffer = std::make_shared<
1408 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07001409 ExternalTexture>(sp<GraphicBuffer>::make(kGreyLevels, 1,
1410 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1411 GRALLOC_USAGE_SW_READ_OFTEN |
1412 GRALLOC_USAGE_SW_WRITE_OFTEN |
1413 GRALLOC_USAGE_HW_RENDER |
1414 GRALLOC_USAGE_HW_TEXTURE,
1415 "output"),
Alec Mouri5a493722022-01-26 16:43:02 -08001416 *mRE,
1417 renderengine::impl::ExternalTexture::Usage::READABLE |
1418 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
1419 ASSERT_EQ(0, mBuffer->getBuffer()->initCheck());
1420
1421 const renderengine::LayerSettings layer{.geometry.boundaries = rect.toFloatRect(),
1422 .source =
1423 renderengine::PixelSource{
1424 .buffer =
1425 renderengine::Buffer{
1426 .buffer =
1427 std::move(buf),
1428 .usePremultipliedAlpha =
1429 true,
1430 },
1431 },
1432 .alpha = 1.0f,
1433 .sourceDataspace = sourceDataspace};
1434
1435 std::vector<renderengine::LayerSettings> layers{layer};
1436 invokeDraw(display, layers);
1437
1438 ColorSpace displayP3 = ColorSpace::DisplayP3();
1439 ColorSpace bt2020 = ColorSpace::BT2020();
1440
1441 tonemap::Metadata metadata{.displayMaxLuminance = 750.0f};
1442
1443 auto generator = [=](Point location) {
1444 const double normColor = static_cast<double>(location.x) / (kGreyLevels - 1);
1445 const vec3 rgb = vec3(normColor, normColor, normColor);
1446
1447 const vec3 linearRGB = eotf(rgb);
1448
1449 const vec3 xyz = bt2020.getRGBtoXYZ() * linearRGB;
1450
1451 const vec3 scaledXYZ = scaleOotf(xyz, kCurrentLuminanceNits);
Alec Mouri196b0f22022-03-04 22:13:48 +00001452 const auto gains =
Alec Mouri5a493722022-01-26 16:43:02 -08001453 tonemap::getToneMapper()
1454 ->lookupTonemapGain(static_cast<aidl::android::hardware::graphics::common::
1455 Dataspace>(sourceDataspace),
1456 static_cast<aidl::android::hardware::graphics::common::
1457 Dataspace>(
1458 ui::Dataspace::DISPLAY_P3),
Alec Mouri196b0f22022-03-04 22:13:48 +00001459 {tonemap::
1460 Color{.linearRGB =
1461 scaleOotf(linearRGB,
1462 kCurrentLuminanceNits),
1463 .xyz = scaledXYZ}},
Alec Mouri5a493722022-01-26 16:43:02 -08001464 metadata);
Alec Mouri196b0f22022-03-04 22:13:48 +00001465 EXPECT_EQ(1, gains.size());
1466 const double gain = gains.front();
Alec Mouri5a493722022-01-26 16:43:02 -08001467 const vec3 normalizedXYZ = scaledXYZ * gain / metadata.displayMaxLuminance;
1468
1469 const vec3 targetRGB = OETF_sRGB(displayP3.getXYZtoRGB() * normalizedXYZ) * 255;
1470 return ubyte4(static_cast<uint8_t>(targetRGB.r), static_cast<uint8_t>(targetRGB.g),
1471 static_cast<uint8_t>(targetRGB.b), 255);
1472 };
1473
1474 expectBufferColor(Rect(kGreyLevels, 1), generator, 2);
1475}
1476
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001477INSTANTIATE_TEST_SUITE_P(PerRenderEngineType, RenderEngineTest,
Alec Mouric16974e2022-09-13 17:35:48 +00001478 testing::Values(std::make_shared<SkiaGLESRenderEngineFactory>(),
Alec Mouri47bcb072023-08-15 02:02:49 +00001479 std::make_shared<SkiaVkRenderEngineFactory>()));
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001480
1481TEST_P(RenderEngineTest, drawLayers_noLayersToDraw) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001482 if (!GetParam()->typeSupported()) {
1483 GTEST_SKIP();
1484 }
Alec Mouric0aae732021-01-12 13:32:18 -08001485 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001486 drawEmptyLayers();
1487}
1488
Sally Qi1fed86e2022-06-23 15:33:52 -07001489TEST_P(RenderEngineTest, drawLayers_fillRedBufferAndEmptyBuffer) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001490 if (!GetParam()->typeSupported()) {
1491 GTEST_SKIP();
1492 }
Sally Qi1fed86e2022-06-23 15:33:52 -07001493 initializeRenderEngine();
1494 renderengine::DisplaySettings settings;
1495 settings.physicalDisplay = fullscreenRect();
1496 settings.clip = fullscreenRect();
1497 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1498
1499 // add a red layer
1500 renderengine::LayerSettings layerOne{
1501 .geometry.boundaries = fullscreenRect().toFloatRect(),
1502 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
1503 .alpha = 1.f,
1504 };
1505
1506 std::vector<renderengine::LayerSettings> layersFirst{layerOne};
1507 invokeDraw(settings, layersFirst);
1508 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
1509
1510 // re-draw with an empty layer above it, and we get a transparent black one
1511 std::vector<renderengine::LayerSettings> layersSecond;
1512 invokeDraw(settings, layersSecond);
1513 expectBufferColor(fullscreenRect(), 0, 0, 0, 0);
1514}
1515
Ana Krulec07b98df2021-01-07 14:38:40 -08001516TEST_P(RenderEngineTest, drawLayers_withoutBuffers_withColorTransform) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001517 if (!GetParam()->typeSupported()) {
1518 GTEST_SKIP();
1519 }
Alec Mouria90a5702021-04-16 16:36:21 +00001520 initializeRenderEngine();
Ana Krulec07b98df2021-01-07 14:38:40 -08001521
1522 renderengine::DisplaySettings settings;
1523 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1524 settings.physicalDisplay = fullscreenRect();
1525 settings.clip = fullscreenRect();
1526
1527 // 255, 255, 255, 255 is full opaque white.
Alec Mouri4049b532021-10-15 20:59:33 -07001528 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
1529 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Ana Krulec07b98df2021-01-07 14:38:40 -08001530 // Create layer with given color.
1531 renderengine::LayerSettings bgLayer;
1532 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1533 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1534 bgLayer.source.solidColor = half3(backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1535 backgroundColor.b / 255.0f);
1536 bgLayer.alpha = backgroundColor.a / 255.0f;
1537 // Transform the red color.
1538 bgLayer.colorTransform = mat4(-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
1539
Sally Qi59a9f502021-10-12 18:53:23 +00001540 std::vector<renderengine::LayerSettings> layers;
1541 layers.push_back(bgLayer);
Ana Krulec07b98df2021-01-07 14:38:40 -08001542
Alec Mouric0aae732021-01-12 13:32:18 -08001543 invokeDraw(settings, layers);
Ana Krulec07b98df2021-01-07 14:38:40 -08001544
1545 // Expect to see full opaque pixel (with inverted red from the transform).
Alec Mouric0aae732021-01-12 13:32:18 -08001546 expectBufferColor(Rect(0, 0, 10, 10), 0.f, backgroundColor.g, backgroundColor.b,
Ana Krulec07b98df2021-01-07 14:38:40 -08001547 backgroundColor.a);
1548}
1549
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001550TEST_P(RenderEngineTest, drawLayers_nullOutputBuffer) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001551 if (!GetParam()->typeSupported()) {
1552 GTEST_SKIP();
1553 }
Alec Mouric0aae732021-01-12 13:32:18 -08001554 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001555
Alec Mourid43ccab2019-03-13 12:23:45 -07001556 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001557 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Sally Qi59a9f502021-10-12 18:53:23 +00001558 std::vector<renderengine::LayerSettings> layers;
Alec Mourid43ccab2019-03-13 12:23:45 -07001559 renderengine::LayerSettings layer;
1560 layer.geometry.boundaries = fullscreenRect().toFloatRect();
1561 BufferSourceVariant<ForceOpaqueBufferVariant>::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
Sally Qi59a9f502021-10-12 18:53:23 +00001562 layers.push_back(layer);
Alec Mourif29700f2023-08-17 21:53:31 +00001563 ftl::Future<FenceResult> future = mRE->drawLayers(settings, layers, nullptr, base::unique_fd());
Alec Mourid43ccab2019-03-13 12:23:45 -07001564
Patrick Williams2e9748f2022-08-09 22:48:18 +00001565 ASSERT_TRUE(future.valid());
1566 auto result = future.get();
1567 ASSERT_FALSE(result.ok());
1568 ASSERT_EQ(BAD_VALUE, result.error());
Alec Mourid43ccab2019-03-13 12:23:45 -07001569}
1570
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001571TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001572 if (!GetParam()->typeSupported()) {
1573 GTEST_SKIP();
1574 }
Alec Mouric0aae732021-01-12 13:32:18 -08001575 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001576 fillRedBuffer<ColorSourceVariant>();
1577}
1578
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001579TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001580 if (!GetParam()->typeSupported()) {
1581 GTEST_SKIP();
1582 }
Alec Mouric0aae732021-01-12 13:32:18 -08001583 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001584 fillGreenBuffer<ColorSourceVariant>();
1585}
1586
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001587TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001588 if (!GetParam()->typeSupported()) {
1589 GTEST_SKIP();
1590 }
Alec Mouric0aae732021-01-12 13:32:18 -08001591 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001592 fillBlueBuffer<ColorSourceVariant>();
1593}
1594
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001595TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001596 if (!GetParam()->typeSupported()) {
1597 GTEST_SKIP();
1598 }
Alec Mouric0aae732021-01-12 13:32:18 -08001599 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001600 fillRedTransparentBuffer<ColorSourceVariant>();
1601}
1602
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001603TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001604 if (!GetParam()->typeSupported()) {
1605 GTEST_SKIP();
1606 }
Alec Mouric0aae732021-01-12 13:32:18 -08001607 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001608 fillBufferPhysicalOffset<ColorSourceVariant>();
1609}
1610
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001611TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001612 if (!GetParam()->typeSupported()) {
1613 GTEST_SKIP();
1614 }
Alec Mouric0aae732021-01-12 13:32:18 -08001615 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001616 fillBufferCheckersRotate0<ColorSourceVariant>();
1617}
1618
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001619TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001620 if (!GetParam()->typeSupported()) {
1621 GTEST_SKIP();
1622 }
Alec Mouric0aae732021-01-12 13:32:18 -08001623 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001624 fillBufferCheckersRotate90<ColorSourceVariant>();
1625}
1626
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001627TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001628 if (!GetParam()->typeSupported()) {
1629 GTEST_SKIP();
1630 }
Alec Mouric0aae732021-01-12 13:32:18 -08001631 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001632 fillBufferCheckersRotate180<ColorSourceVariant>();
1633}
1634
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001635TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001636 if (!GetParam()->typeSupported()) {
1637 GTEST_SKIP();
1638 }
Alec Mouric0aae732021-01-12 13:32:18 -08001639 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001640 fillBufferCheckersRotate270<ColorSourceVariant>();
1641}
1642
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001643TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001644 if (!GetParam()->typeSupported()) {
1645 GTEST_SKIP();
1646 }
Alec Mouric0aae732021-01-12 13:32:18 -08001647 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001648 fillBufferLayerTransform<ColorSourceVariant>();
1649}
1650
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001651TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001652 if (!GetParam()->typeSupported()) {
1653 GTEST_SKIP();
1654 }
Alec Mouric0aae732021-01-12 13:32:18 -08001655 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08001656 fillBufferColorTransform<ColorSourceVariant>();
1657}
1658
Sally Qi2019fd22021-11-22 10:19:04 -08001659TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_sourceDataspace) {
1660 const auto& renderEngineFactory = GetParam();
1661 // skip for non color management
Alec Mouri47bcb072023-08-15 02:02:49 +00001662 if (!renderEngineFactory->typeSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001663 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001664 }
1665
1666 initializeRenderEngine();
1667 fillBufferColorTransformAndSourceDataspace<ColorSourceVariant>();
1668}
1669
1670TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_outputDataspace) {
1671 const auto& renderEngineFactory = GetParam();
1672 // skip for non color management
Alec Mouri47bcb072023-08-15 02:02:49 +00001673 if (!renderEngineFactory->typeSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001674 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001675 }
1676
1677 initializeRenderEngine();
1678 fillBufferColorTransformAndOutputDataspace<ColorSourceVariant>();
1679}
1680
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001681TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_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 Mouri7c94edb2018-12-03 21:23:26 -08001686 fillBufferWithRoundedCorners<ColorSourceVariant>();
1687}
1688
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001689TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_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();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001694 fillBufferColorTransformZeroLayerAlpha<ColorSourceVariant>();
1695}
1696
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001697TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_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();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001702 fillBufferAndBlurBackground<ColorSourceVariant>();
1703}
1704
Alec Mourie8489fd2021-04-29 16:08:56 -07001705TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_colorSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001706 if (!GetParam()->typeSupported()) {
1707 GTEST_SKIP();
1708 }
Alec Mourie8489fd2021-04-29 16:08:56 -07001709 initializeRenderEngine();
1710 fillSmallLayerAndBlurBackground<ColorSourceVariant>();
1711}
1712
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001713TEST_P(RenderEngineTest, drawLayers_overlayCorners_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 Mourie7d1d4a2019-02-05 01:13:46 +00001718 overlayCorners<ColorSourceVariant>();
1719}
1720
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001721TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_opaqueBufferSource) {
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 Mouri0d5e1eb2018-11-10 20:40:12 -08001726 fillRedBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1727}
1728
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001729TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_opaqueBufferSource) {
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 Mouri0d5e1eb2018-11-10 20:40:12 -08001734 fillGreenBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1735}
1736
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001737TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001738 if (!GetParam()->typeSupported()) {
1739 GTEST_SKIP();
1740 }
Alec Mouric0aae732021-01-12 13:32:18 -08001741 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001742 fillBlueBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1743}
1744
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001745TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001746 if (!GetParam()->typeSupported()) {
1747 GTEST_SKIP();
1748 }
Alec Mouric0aae732021-01-12 13:32:18 -08001749 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001750 fillRedTransparentBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1751}
1752
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001753TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001754 if (!GetParam()->typeSupported()) {
1755 GTEST_SKIP();
1756 }
Alec Mouric0aae732021-01-12 13:32:18 -08001757 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001758 fillBufferPhysicalOffset<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1759}
1760
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001761TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001762 if (!GetParam()->typeSupported()) {
1763 GTEST_SKIP();
1764 }
Alec Mouric0aae732021-01-12 13:32:18 -08001765 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001766 fillBufferCheckersRotate0<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1767}
1768
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001769TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001770 if (!GetParam()->typeSupported()) {
1771 GTEST_SKIP();
1772 }
Alec Mouric0aae732021-01-12 13:32:18 -08001773 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001774 fillBufferCheckersRotate90<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1775}
1776
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001777TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001778 if (!GetParam()->typeSupported()) {
1779 GTEST_SKIP();
1780 }
Alec Mouric0aae732021-01-12 13:32:18 -08001781 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001782 fillBufferCheckersRotate180<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1783}
1784
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001785TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001786 if (!GetParam()->typeSupported()) {
1787 GTEST_SKIP();
1788 }
Alec Mouric0aae732021-01-12 13:32:18 -08001789 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001790 fillBufferCheckersRotate270<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1791}
1792
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001793TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001794 if (!GetParam()->typeSupported()) {
1795 GTEST_SKIP();
1796 }
Alec Mouric0aae732021-01-12 13:32:18 -08001797 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001798 fillBufferLayerTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1799}
1800
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001801TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001802 if (!GetParam()->typeSupported()) {
1803 GTEST_SKIP();
1804 }
Alec Mouric0aae732021-01-12 13:32:18 -08001805 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08001806 fillBufferColorTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1807}
1808
Sally Qi2019fd22021-11-22 10:19:04 -08001809TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndSourceDataspace_opaqueBufferSource) {
1810 const auto& renderEngineFactory = GetParam();
1811 // skip for non color management
Alec Mouri47bcb072023-08-15 02:02:49 +00001812 if (!renderEngineFactory->typeSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001813 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001814 }
1815
1816 initializeRenderEngine();
1817 fillBufferColorTransformAndSourceDataspace<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1818}
1819
1820TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndOutputDataspace_opaqueBufferSource) {
1821 const auto& renderEngineFactory = GetParam();
1822 // skip for non color management
Alec Mouri47bcb072023-08-15 02:02:49 +00001823 if (!renderEngineFactory->typeSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001824 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001825 }
1826
1827 initializeRenderEngine();
1828 fillBufferColorTransformAndOutputDataspace<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1829}
1830
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001831TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_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 Mouri7c94edb2018-12-03 21:23:26 -08001836 fillBufferWithRoundedCorners<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1837}
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001838
Alec Mouric0aae732021-01-12 13:32:18 -08001839TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_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();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001844 fillBufferColorTransformZeroLayerAlpha<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1845}
Alec Mouri7c94edb2018-12-03 21:23:26 -08001846
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001847TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_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();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001852 fillBufferAndBlurBackground<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1853}
1854
Alec Mourie8489fd2021-04-29 16:08:56 -07001855TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_opaqueBufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001856 if (!GetParam()->typeSupported()) {
1857 GTEST_SKIP();
1858 }
Alec Mourie8489fd2021-04-29 16:08:56 -07001859 initializeRenderEngine();
1860 fillSmallLayerAndBlurBackground<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1861}
1862
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001863TEST_P(RenderEngineTest, drawLayers_overlayCorners_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 Mourie7d1d4a2019-02-05 01:13:46 +00001868 overlayCorners<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1869}
1870
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001871TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_bufferSource) {
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 fillRedBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1877}
1878
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001879TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_bufferSource) {
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 fillGreenBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1885}
1886
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001887TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001888 if (!GetParam()->typeSupported()) {
1889 GTEST_SKIP();
1890 }
Alec Mouric0aae732021-01-12 13:32:18 -08001891 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001892 fillBlueBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1893}
1894
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001895TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001896 if (!GetParam()->typeSupported()) {
1897 GTEST_SKIP();
1898 }
Alec Mouric0aae732021-01-12 13:32:18 -08001899 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001900 fillRedTransparentBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1901}
1902
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001903TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001904 if (!GetParam()->typeSupported()) {
1905 GTEST_SKIP();
1906 }
Alec Mouric0aae732021-01-12 13:32:18 -08001907 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001908 fillBufferPhysicalOffset<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1909}
1910
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001911TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001912 if (!GetParam()->typeSupported()) {
1913 GTEST_SKIP();
1914 }
Alec Mouric0aae732021-01-12 13:32:18 -08001915 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001916 fillBufferCheckersRotate0<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1917}
1918
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001919TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001920 if (!GetParam()->typeSupported()) {
1921 GTEST_SKIP();
1922 }
Alec Mouric0aae732021-01-12 13:32:18 -08001923 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001924 fillBufferCheckersRotate90<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1925}
1926
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001927TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001928 if (!GetParam()->typeSupported()) {
1929 GTEST_SKIP();
1930 }
Alec Mouric0aae732021-01-12 13:32:18 -08001931 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001932 fillBufferCheckersRotate180<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1933}
1934
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001935TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001936 if (!GetParam()->typeSupported()) {
1937 GTEST_SKIP();
1938 }
Alec Mouric0aae732021-01-12 13:32:18 -08001939 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001940 fillBufferCheckersRotate270<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1941}
1942
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001943TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001944 if (!GetParam()->typeSupported()) {
1945 GTEST_SKIP();
1946 }
Alec Mouric0aae732021-01-12 13:32:18 -08001947 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001948 fillBufferLayerTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1949}
1950
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001951TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001952 if (!GetParam()->typeSupported()) {
1953 GTEST_SKIP();
1954 }
Alec Mouric0aae732021-01-12 13:32:18 -08001955 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08001956 fillBufferColorTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1957}
1958
Sally Qi2019fd22021-11-22 10:19:04 -08001959TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndSourceDataspace_bufferSource) {
1960 const auto& renderEngineFactory = GetParam();
1961 // skip for non color management
Alec Mouri47bcb072023-08-15 02:02:49 +00001962 if (!renderEngineFactory->typeSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001963 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001964 }
1965
1966 initializeRenderEngine();
1967 fillBufferColorTransformAndSourceDataspace<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1968}
1969
1970TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndOutputDataspace_bufferSource) {
1971 const auto& renderEngineFactory = GetParam();
1972 // skip for non color management
Alec Mouri47bcb072023-08-15 02:02:49 +00001973 if (!renderEngineFactory->typeSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001974 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001975 }
1976
1977 initializeRenderEngine();
1978 fillBufferColorTransformAndOutputDataspace<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1979}
1980
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001981TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_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 Mouri7c94edb2018-12-03 21:23:26 -08001986 fillBufferWithRoundedCorners<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1987}
1988
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001989TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_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();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001994 fillBufferColorTransformZeroLayerAlpha<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1995}
1996
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001997TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_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();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08002002 fillBufferAndBlurBackground<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2003}
2004
Alec Mourie8489fd2021-04-29 16:08:56 -07002005TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_bufferSource) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002006 if (!GetParam()->typeSupported()) {
2007 GTEST_SKIP();
2008 }
Alec Mourie8489fd2021-04-29 16:08:56 -07002009 initializeRenderEngine();
2010 fillSmallLayerAndBlurBackground<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2011}
2012
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002013TEST_P(RenderEngineTest, drawLayers_overlayCorners_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 Mourie7d1d4a2019-02-05 01:13:46 +00002018 overlayCorners<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2019}
2020
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002021TEST_P(RenderEngineTest, drawLayers_fillBufferTextureTransform) {
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 fillBufferTextureTransform();
2027}
2028
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002029TEST_P(RenderEngineTest, drawLayers_fillBuffer_premultipliesAlpha) {
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 fillBufferWithPremultiplyAlpha();
2035}
2036
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002037TEST_P(RenderEngineTest, drawLayers_fillBuffer_withoutPremultiplyingAlpha) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002038 if (!GetParam()->typeSupported()) {
2039 GTEST_SKIP();
2040 }
Alec Mouric0aae732021-01-12 13:32:18 -08002041 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002042 fillBufferWithoutPremultiplyAlpha();
2043}
2044
Alec Mouribd17b3b2020-12-17 11:08:30 -08002045TEST_P(RenderEngineTest, drawLayers_fillShadow_castsWithoutCasterLayer) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002046 if (!GetParam()->typeSupported()) {
2047 GTEST_SKIP();
2048 }
Alec Mouric0aae732021-01-12 13:32:18 -08002049 initializeRenderEngine();
Alec Mouribd17b3b2020-12-17 11:08:30 -08002050
Alec Mouri4049b532021-10-15 20:59:33 -07002051 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2052 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Alec Mouribd17b3b2020-12-17 11:08:30 -08002053 const float shadowLength = 5.0f;
2054 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2055 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
Vishnu Naird9e4f462023-10-06 04:05:45 +00002056 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2057 shadowLength, false /* casterIsTranslucent */);
Alec Mouribd17b3b2020-12-17 11:08:30 -08002058
2059 drawShadowWithoutCaster(casterBounds.toFloatRect(), settings, backgroundColor);
2060 expectShadowColorWithoutCaster(casterBounds.toFloatRect(), settings, backgroundColor);
2061}
2062
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002063TEST_P(RenderEngineTest, drawLayers_fillShadow_casterLayerMinSize) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002064 if (!GetParam()->typeSupported()) {
2065 GTEST_SKIP();
2066 }
Alec Mouric0aae732021-01-12 13:32:18 -08002067 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002068
Alec Mouri4049b532021-10-15 20:59:33 -07002069 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2070 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2071 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2072 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002073 const float shadowLength = 5.0f;
2074 Rect casterBounds(1, 1);
2075 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2076 renderengine::LayerSettings castingLayer;
2077 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2078 castingLayer.alpha = 1.0f;
Vishnu Naird9e4f462023-10-06 04:05:45 +00002079 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2080 shadowLength, false /* casterIsTranslucent */);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002081
2082 drawShadow<ColorSourceVariant>(castingLayer, settings, casterColor, backgroundColor);
2083 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2084}
2085
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002086TEST_P(RenderEngineTest, drawLayers_fillShadow_casterColorLayer) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002087 if (!GetParam()->typeSupported()) {
2088 GTEST_SKIP();
2089 }
Alec Mouric0aae732021-01-12 13:32:18 -08002090 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002091
Alec Mouri4049b532021-10-15 20:59:33 -07002092 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2093 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2094 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2095 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002096 const float shadowLength = 5.0f;
2097 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2098 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2099 renderengine::LayerSettings castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002100 castingLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002101 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2102 castingLayer.alpha = 1.0f;
Vishnu Naird9e4f462023-10-06 04:05:45 +00002103 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2104 shadowLength, false /* casterIsTranslucent */);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002105
2106 drawShadow<ColorSourceVariant>(castingLayer, settings, casterColor, backgroundColor);
2107 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2108}
2109
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002110TEST_P(RenderEngineTest, drawLayers_fillShadow_casterOpaqueBufferLayer) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002111 if (!GetParam()->typeSupported()) {
2112 GTEST_SKIP();
2113 }
Alec Mouric0aae732021-01-12 13:32:18 -08002114 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002115
Alec Mouri4049b532021-10-15 20:59:33 -07002116 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2117 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2118 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2119 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002120 const float shadowLength = 5.0f;
2121 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2122 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2123 renderengine::LayerSettings castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002124 castingLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002125 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2126 castingLayer.alpha = 1.0f;
Vishnu Naird9e4f462023-10-06 04:05:45 +00002127 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2128 shadowLength, false /* casterIsTranslucent */);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002129
2130 drawShadow<BufferSourceVariant<ForceOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2131 backgroundColor);
2132 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2133}
2134
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002135TEST_P(RenderEngineTest, drawLayers_fillShadow_casterWithRoundedCorner) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002136 if (!GetParam()->typeSupported()) {
2137 GTEST_SKIP();
2138 }
Alec Mouric0aae732021-01-12 13:32:18 -08002139 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002140
Alec Mouri4049b532021-10-15 20:59:33 -07002141 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2142 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2143 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2144 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002145 const float shadowLength = 5.0f;
2146 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2147 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2148 renderengine::LayerSettings castingLayer;
2149 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002150 castingLayer.geometry.roundedCornersRadius = {3.0f, 3.0f};
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002151 castingLayer.geometry.roundedCornersCrop = casterBounds.toFloatRect();
2152 castingLayer.alpha = 1.0f;
Vishnu Naird9e4f462023-10-06 04:05:45 +00002153 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2154 shadowLength, false /* casterIsTranslucent */);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002155
2156 drawShadow<BufferSourceVariant<ForceOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2157 backgroundColor);
2158 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2159}
2160
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002161TEST_P(RenderEngineTest, drawLayers_fillShadow_translucentCasterWithAlpha) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002162 if (!GetParam()->typeSupported()) {
2163 GTEST_SKIP();
2164 }
Alec Mouric0aae732021-01-12 13:32:18 -08002165 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002166
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002167 const ubyte4 casterColor(255, 0, 0, 255);
2168 const ubyte4 backgroundColor(255, 255, 255, 255);
2169 const float shadowLength = 5.0f;
2170 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2171 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2172 renderengine::LayerSettings castingLayer;
2173 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2174 castingLayer.alpha = 0.5f;
Vishnu Naird9e4f462023-10-06 04:05:45 +00002175 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2176 shadowLength, true /* casterIsTranslucent */);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002177
2178 drawShadow<BufferSourceVariant<RelaxOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2179 backgroundColor);
2180
2181 // verify only the background since the shadow will draw behind the caster
2182 const float shadowInset = settings.length * -1.0f;
2183 const Rect casterWithShadow =
2184 Rect(casterBounds).inset(shadowInset, shadowInset, shadowInset, shadowInset);
2185 const Region backgroundRegion = Region(fullscreenRect()).subtractSelf(casterWithShadow);
2186 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
2187 backgroundColor.a);
2188}
2189
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002190TEST_P(RenderEngineTest, cleanupPostRender_cleansUpOnce) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002191 if (!GetParam()->typeSupported()) {
2192 GTEST_SKIP();
2193 }
Alec Mouric0aae732021-01-12 13:32:18 -08002194 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002195
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002196 renderengine::DisplaySettings settings;
2197 settings.physicalDisplay = fullscreenRect();
2198 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002199 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002200
Sally Qi59a9f502021-10-12 18:53:23 +00002201 std::vector<renderengine::LayerSettings> layers;
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002202 renderengine::LayerSettings layer;
2203 layer.geometry.boundaries = fullscreenRect().toFloatRect();
2204 BufferSourceVariant<ForceOpaqueBufferVariant>::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
2205 layer.alpha = 1.0;
Sally Qi59a9f502021-10-12 18:53:23 +00002206 layers.push_back(layer);
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002207
Patrick Williams2e9748f2022-08-09 22:48:18 +00002208 ftl::Future<FenceResult> futureOne =
Alec Mourif29700f2023-08-17 21:53:31 +00002209 mRE->drawLayers(settings, layers, mBuffer, base::unique_fd());
Patrick Williams2e9748f2022-08-09 22:48:18 +00002210 ASSERT_TRUE(futureOne.valid());
2211 auto resultOne = futureOne.get();
2212 ASSERT_TRUE(resultOne.ok());
2213 auto fenceOne = resultOne.value();
Sally Qi4cabdd02021-08-05 16:45:57 -07002214
Patrick Williams2e9748f2022-08-09 22:48:18 +00002215 ftl::Future<FenceResult> futureTwo =
Alec Mourif29700f2023-08-17 21:53:31 +00002216 mRE->drawLayers(settings, layers, mBuffer, base::unique_fd(fenceOne->dup()));
Patrick Williams2e9748f2022-08-09 22:48:18 +00002217 ASSERT_TRUE(futureTwo.valid());
2218 auto resultTwo = futureTwo.get();
2219 ASSERT_TRUE(resultTwo.ok());
2220 auto fenceTwo = resultTwo.value();
2221 fenceTwo->waitForever(LOG_TAG);
Derek Sollenbergerec411212021-08-25 10:54:47 -04002222
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002223 // Only cleanup the first time.
Ian Elliott1f0911e2022-09-09 16:31:47 -06002224 if (mRE->canSkipPostRenderCleanup()) {
2225 // Skia's Vk backend may keep the texture alive beyond drawLayersInternal, so
2226 // it never gets added to the cleanup list. In those cases, we can skip.
2227 EXPECT_TRUE(GetParam()->type() == renderengine::RenderEngine::RenderEngineType::SKIA_VK);
2228 } else {
2229 mRE->cleanupPostRender();
2230 EXPECT_TRUE(mRE->canSkipPostRenderCleanup());
2231 }
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002232}
2233
Ana Krulecf9a15d92020-12-11 08:35:00 -08002234TEST_P(RenderEngineTest, testRoundedCornersCrop) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002235 if (!GetParam()->typeSupported()) {
2236 GTEST_SKIP();
2237 }
Alec Mouric0aae732021-01-12 13:32:18 -08002238 initializeRenderEngine();
Ana Krulecf9a15d92020-12-11 08:35:00 -08002239
2240 renderengine::DisplaySettings settings;
2241 settings.physicalDisplay = fullscreenRect();
2242 settings.clip = fullscreenRect();
2243 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2244
Sally Qi59a9f502021-10-12 18:53:23 +00002245 std::vector<renderengine::LayerSettings> layers;
Ana Krulecf9a15d92020-12-11 08:35:00 -08002246
2247 renderengine::LayerSettings redLayer;
2248 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2249 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002250 redLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
2251
Ana Krulecf9a15d92020-12-11 08:35:00 -08002252 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2253 // Red background.
2254 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2255 redLayer.alpha = 1.0f;
2256
Sally Qi59a9f502021-10-12 18:53:23 +00002257 layers.push_back(redLayer);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002258
2259 // Green layer with 1/3 size.
2260 renderengine::LayerSettings greenLayer;
2261 greenLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2262 greenLayer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002263 greenLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
Ana Krulecf9a15d92020-12-11 08:35:00 -08002264 // Bottom right corner is not going to be rounded.
2265 greenLayer.geometry.roundedCornersCrop =
2266 Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3, DEFAULT_DISPLAY_HEIGHT,
2267 DEFAULT_DISPLAY_HEIGHT)
2268 .toFloatRect();
2269 greenLayer.source.solidColor = half3(0.0f, 1.0f, 0.0f);
2270 greenLayer.alpha = 1.0f;
2271
Sally Qi59a9f502021-10-12 18:53:23 +00002272 layers.push_back(greenLayer);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002273
Alec Mouric0aae732021-01-12 13:32:18 -08002274 invokeDraw(settings, layers);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002275
2276 // Corners should be ignored...
2277 // Screen size: width is 128, height is 256.
2278 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 0);
2279 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, 0, DEFAULT_DISPLAY_WIDTH, 1), 0, 0, 0, 0);
2280 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT - 1, 1, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
2281 // Bottom right corner is kept out of the clipping, and it's green.
2282 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1,
2283 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
2284 0, 255, 0, 255);
2285}
2286
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002287TEST_P(RenderEngineTest, testRoundedCornersParentCrop) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002288 if (!GetParam()->typeSupported()) {
2289 GTEST_SKIP();
2290 }
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002291 initializeRenderEngine();
2292
2293 renderengine::DisplaySettings settings;
2294 settings.physicalDisplay = fullscreenRect();
2295 settings.clip = fullscreenRect();
2296 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2297
Sally Qi59a9f502021-10-12 18:53:23 +00002298 std::vector<renderengine::LayerSettings> layers;
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002299
2300 renderengine::LayerSettings redLayer;
2301 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2302 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002303 redLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002304 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2305 // Red background.
2306 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2307 redLayer.alpha = 1.0f;
2308
Sally Qi59a9f502021-10-12 18:53:23 +00002309 layers.push_back(redLayer);
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002310
2311 // Green layer with 1/2 size with parent crop rect.
2312 renderengine::LayerSettings greenLayer = redLayer;
2313 greenLayer.geometry.boundaries =
2314 FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT / 2);
2315 greenLayer.source.solidColor = half3(0.0f, 1.0f, 0.0f);
2316
Sally Qi59a9f502021-10-12 18:53:23 +00002317 layers.push_back(greenLayer);
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002318
2319 invokeDraw(settings, layers);
2320
2321 // Due to roundedCornersRadius, the corners are untouched.
2322 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2323 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2324 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2325 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2326
2327 // top middle should be green and the bottom middle red
2328 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, 0), 0, 255, 0, 255);
2329 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0, 255);
2330
2331 // the bottom edge of the green layer should not be rounded
2332 expectBufferColor(Point(0, (DEFAULT_DISPLAY_HEIGHT / 2) - 1), 0, 255, 0, 255);
2333}
2334
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002335TEST_P(RenderEngineTest, testRoundedCornersParentCropSmallBounds) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002336 if (!GetParam()->typeSupported()) {
2337 GTEST_SKIP();
2338 }
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002339 initializeRenderEngine();
2340
2341 renderengine::DisplaySettings settings;
2342 settings.physicalDisplay = fullscreenRect();
2343 settings.clip = fullscreenRect();
2344 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2345
Sally Qi59a9f502021-10-12 18:53:23 +00002346 std::vector<renderengine::LayerSettings> layers;
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002347
2348 renderengine::LayerSettings redLayer;
2349 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2350 redLayer.geometry.boundaries = FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, 32);
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002351 redLayer.geometry.roundedCornersRadius = {64.0f, 64.0f};
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002352 redLayer.geometry.roundedCornersCrop = FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, 128);
2353 // Red background.
2354 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2355 redLayer.alpha = 1.0f;
2356
Sally Qi59a9f502021-10-12 18:53:23 +00002357 layers.push_back(redLayer);
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002358 invokeDraw(settings, layers);
2359
2360 // Due to roundedCornersRadius, the top corners are untouched.
2361 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2362 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2363
2364 // ensure that the entire height of the red layer was clipped by the rounded corners crop.
2365 expectBufferColor(Point(0, 31), 0, 0, 0, 0);
2366 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 31), 0, 0, 0, 0);
2367
2368 // the bottom middle should be red
2369 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, 31), 255, 0, 0, 255);
2370}
2371
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002372TEST_P(RenderEngineTest, testRoundedCornersXY) {
2373 if (GetParam()->type() != renderengine::RenderEngine::RenderEngineType::SKIA_GL) {
2374 GTEST_SKIP();
2375 }
2376
2377 initializeRenderEngine();
2378
2379 renderengine::DisplaySettings settings;
2380 settings.physicalDisplay = fullscreenRect();
2381 settings.clip = fullscreenRect();
2382 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2383
2384 std::vector<renderengine::LayerSettings> layers;
2385
2386 renderengine::LayerSettings redLayer;
2387 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2388 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
2389 redLayer.geometry.roundedCornersRadius = {5.0f, 20.0f};
2390 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2391 // Red background.
2392 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2393 redLayer.alpha = 1.0f;
2394
2395 layers.push_back(redLayer);
2396
2397 invokeDraw(settings, layers);
2398
2399 // Due to roundedCornersRadius, the corners are untouched.
2400 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2401 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2402 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2403 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2404
2405 // Y-axis draws a larger radius, check that its untouched as well
2406 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 5), 0, 0, 0, 0);
2407 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 5), 0, 0, 0, 0);
2408 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 5), 0, 0, 0, 0);
2409 expectBufferColor(Point(0, 5), 0, 0, 0, 0);
2410
2411 // middle should be red
2412 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0, 255);
2413}
2414
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002415TEST_P(RenderEngineTest, testClear) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002416 if (!GetParam()->typeSupported()) {
2417 GTEST_SKIP();
2418 }
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002419 initializeRenderEngine();
2420
2421 const auto rect = fullscreenRect();
2422 const renderengine::DisplaySettings display{
2423 .physicalDisplay = rect,
2424 .clip = rect,
2425 };
2426
2427 const renderengine::LayerSettings redLayer{
2428 .geometry.boundaries = rect.toFloatRect(),
2429 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
2430 .alpha = 1.0f,
2431 };
2432
2433 // This mimics prepareClearClientComposition. This layer should overwrite
2434 // the redLayer, so that the buffer is transparent, rather than red.
2435 const renderengine::LayerSettings clearLayer{
2436 .geometry.boundaries = rect.toFloatRect(),
2437 .source.solidColor = half3(0.0f, 0.0f, 0.0f),
2438 .alpha = 0.0f,
2439 .disableBlending = true,
2440 };
2441
Sally Qi59a9f502021-10-12 18:53:23 +00002442 std::vector<renderengine::LayerSettings> layers{redLayer, clearLayer};
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002443 invokeDraw(display, layers);
2444 expectBufferColor(rect, 0, 0, 0, 0);
2445}
2446
2447TEST_P(RenderEngineTest, testDisableBlendingBuffer) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002448 if (!GetParam()->typeSupported()) {
2449 GTEST_SKIP();
2450 }
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002451 initializeRenderEngine();
2452
2453 const auto rect = Rect(0, 0, 1, 1);
2454 const renderengine::DisplaySettings display{
2455 .physicalDisplay = rect,
2456 .clip = rect,
2457 };
2458
2459 const renderengine::LayerSettings redLayer{
2460 .geometry.boundaries = rect.toFloatRect(),
2461 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
2462 .alpha = 1.0f,
2463 };
2464
2465 // The next layer will overwrite redLayer with a GraphicBuffer that is green
2466 // applied with a translucent alpha.
Alec Mouria90a5702021-04-16 16:36:21 +00002467 const auto buf = allocateSourceBuffer(1, 1);
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002468 {
2469 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00002470 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2471 reinterpret_cast<void**>(&pixels));
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002472 pixels[0] = 0;
2473 pixels[1] = 255;
2474 pixels[2] = 0;
2475 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00002476 buf->getBuffer()->unlock();
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002477 }
2478
2479 const renderengine::LayerSettings greenLayer{
2480 .geometry.boundaries = rect.toFloatRect(),
2481 .source =
2482 renderengine::PixelSource{
2483 .buffer =
2484 renderengine::Buffer{
2485 .buffer = buf,
2486 .usePremultipliedAlpha = true,
2487 },
2488 },
2489 .alpha = 0.5f,
2490 .disableBlending = true,
2491 };
2492
Sally Qi59a9f502021-10-12 18:53:23 +00002493 std::vector<renderengine::LayerSettings> layers{redLayer, greenLayer};
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002494 invokeDraw(display, layers);
2495 expectBufferColor(rect, 0, 128, 0, 128);
2496}
2497
Tianhao Yao67dd7122022-02-22 17:48:33 +00002498TEST_P(RenderEngineTest, testBorder) {
2499 if (GetParam()->type() != renderengine::RenderEngine::RenderEngineType::SKIA_GL) {
2500 GTEST_SKIP();
2501 }
2502
Tianhao Yao67dd7122022-02-22 17:48:33 +00002503 initializeRenderEngine();
2504
2505 const ui::Dataspace dataspace = ui::Dataspace::V0_SRGB;
2506
2507 const auto displayRect = Rect(1080, 2280);
2508 renderengine::DisplaySettings display{
2509 .physicalDisplay = displayRect,
2510 .clip = displayRect,
2511 .outputDataspace = dataspace,
2512 };
2513 display.borderInfoList.clear();
2514 renderengine::BorderRenderInfo info;
2515 info.combinedRegion = Region(Rect(99, 99, 199, 199));
Tianhao Yao10cea3c2022-03-30 01:37:22 +00002516 info.width = 20.0f;
2517 info.color = half4{1.0f, 128.0f / 255.0f, 0.0f, 1.0f};
Tianhao Yao67dd7122022-02-22 17:48:33 +00002518 display.borderInfoList.emplace_back(info);
2519
2520 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2521 const renderengine::LayerSettings greenLayer{
2522 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2523 .source =
2524 renderengine::PixelSource{
2525 .buffer =
2526 renderengine::Buffer{
2527 .buffer = greenBuffer,
2528 .usePremultipliedAlpha = true,
2529 },
2530 },
2531 .alpha = 1.0f,
2532 .sourceDataspace = dataspace,
2533 .whitePointNits = 200.f,
2534 };
2535
2536 std::vector<renderengine::LayerSettings> layers;
2537 layers.emplace_back(greenLayer);
2538 invokeDraw(display, layers);
2539
2540 expectBufferColor(Rect(99, 99, 101, 101), 255, 128, 0, 255, 1);
2541}
2542
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002543TEST_P(RenderEngineTest, testDimming) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002544 if (!GetParam()->typeSupported()) {
2545 GTEST_SKIP();
2546 }
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002547 initializeRenderEngine();
2548
Alec Mouri85065692022-03-18 00:58:26 +00002549 const ui::Dataspace dataspace = ui::Dataspace::V0_SRGB_LINEAR;
2550
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002551 const auto displayRect = Rect(3, 1);
2552 const renderengine::DisplaySettings display{
2553 .physicalDisplay = displayRect,
2554 .clip = displayRect,
Alec Mouri85065692022-03-18 00:58:26 +00002555 .outputDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002556 .targetLuminanceNits = 1000.f,
2557 };
2558
2559 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2560 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2561 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2562
2563 const renderengine::LayerSettings greenLayer{
2564 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2565 .source =
2566 renderengine::PixelSource{
2567 .buffer =
2568 renderengine::Buffer{
2569 .buffer = greenBuffer,
2570 .usePremultipliedAlpha = true,
2571 },
2572 },
2573 .alpha = 1.0f,
Alec Mouri85065692022-03-18 00:58:26 +00002574 .sourceDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002575 .whitePointNits = 200.f,
2576 };
2577
2578 const renderengine::LayerSettings blueLayer{
2579 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2580 .source =
2581 renderengine::PixelSource{
2582 .buffer =
2583 renderengine::Buffer{
2584 .buffer = blueBuffer,
2585 .usePremultipliedAlpha = true,
2586 },
2587 },
2588 .alpha = 1.0f,
Alec Mouri85065692022-03-18 00:58:26 +00002589 .sourceDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002590 .whitePointNits = 1000.f / 51.f,
2591 };
2592
2593 const renderengine::LayerSettings redLayer{
2594 .geometry.boundaries = FloatRect(2.f, 0.f, 3.f, 1.f),
2595 .source =
2596 renderengine::PixelSource{
2597 .buffer =
2598 renderengine::Buffer{
2599 .buffer = redBuffer,
2600 .usePremultipliedAlpha = true,
2601 },
2602 },
2603 .alpha = 1.0f,
Alec Mouri85065692022-03-18 00:58:26 +00002604 .sourceDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002605 // When the white point is not set for a layer, just ignore it and treat it as the same
2606 // as the max layer
2607 .whitePointNits = -1.f,
2608 };
2609
2610 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer, redLayer};
2611 invokeDraw(display, layers);
2612
2613 expectBufferColor(Rect(1, 1), 0, 51, 0, 255, 1);
2614 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 5, 255, 1);
2615 expectBufferColor(Rect(2, 0, 3, 1), 51, 0, 0, 255, 1);
2616}
2617
Alec Mouri85065692022-03-18 00:58:26 +00002618TEST_P(RenderEngineTest, testDimming_inGammaSpace) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002619 if (!GetParam()->typeSupported()) {
2620 GTEST_SKIP();
2621 }
Alec Mouri85065692022-03-18 00:58:26 +00002622 initializeRenderEngine();
2623
2624 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2625 ui::Dataspace::TRANSFER_GAMMA2_2 |
2626 ui::Dataspace::RANGE_FULL);
2627
2628 const auto displayRect = Rect(3, 1);
2629 const renderengine::DisplaySettings display{
2630 .physicalDisplay = displayRect,
2631 .clip = displayRect,
2632 .outputDataspace = dataspace,
2633 .targetLuminanceNits = 1000.f,
2634 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2635 };
2636
2637 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2638 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2639 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2640
2641 const renderengine::LayerSettings greenLayer{
2642 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2643 .source =
2644 renderengine::PixelSource{
2645 .buffer =
2646 renderengine::Buffer{
2647 .buffer = greenBuffer,
2648 .usePremultipliedAlpha = true,
2649 },
2650 },
2651 .alpha = 1.0f,
2652 .sourceDataspace = dataspace,
2653 .whitePointNits = 200.f,
2654 };
2655
2656 const renderengine::LayerSettings blueLayer{
2657 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2658 .source =
2659 renderengine::PixelSource{
2660 .buffer =
2661 renderengine::Buffer{
2662 .buffer = blueBuffer,
2663 .usePremultipliedAlpha = true,
2664 },
2665 },
2666 .alpha = 1.0f,
2667 .sourceDataspace = dataspace,
2668 .whitePointNits = 1000.f / 51.f,
2669 };
2670
2671 const renderengine::LayerSettings redLayer{
2672 .geometry.boundaries = FloatRect(2.f, 0.f, 3.f, 1.f),
2673 .source =
2674 renderengine::PixelSource{
2675 .buffer =
2676 renderengine::Buffer{
2677 .buffer = redBuffer,
2678 .usePremultipliedAlpha = true,
2679 },
2680 },
2681 .alpha = 1.0f,
2682 .sourceDataspace = dataspace,
2683 // When the white point is not set for a layer, just ignore it and treat it as the same
2684 // as the max layer
2685 .whitePointNits = -1.f,
2686 };
2687
2688 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer, redLayer};
2689 invokeDraw(display, layers);
2690
2691 expectBufferColor(Rect(1, 1), 0, 122, 0, 255, 1);
2692 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 42, 255, 1);
2693 expectBufferColor(Rect(2, 0, 3, 1), 122, 0, 0, 255, 1);
2694}
2695
Alec Mouri9bcd1d12022-04-21 22:16:56 +00002696TEST_P(RenderEngineTest, testDimming_inGammaSpace_withDisplayColorTransform) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002697 if (!GetParam()->typeSupported()) {
2698 GTEST_SKIP();
2699 }
Alec Mouri9bcd1d12022-04-21 22:16:56 +00002700 initializeRenderEngine();
2701
2702 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2703 ui::Dataspace::TRANSFER_GAMMA2_2 |
2704 ui::Dataspace::RANGE_FULL);
2705
2706 const auto displayRect = Rect(3, 1);
2707 const renderengine::DisplaySettings display{
2708 .physicalDisplay = displayRect,
2709 .clip = displayRect,
2710 .outputDataspace = dataspace,
2711 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
2712 .targetLuminanceNits = 1000.f,
2713 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2714 };
2715
2716 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2717 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2718 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2719
2720 const renderengine::LayerSettings greenLayer{
2721 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2722 .source =
2723 renderengine::PixelSource{
2724 .buffer =
2725 renderengine::Buffer{
2726 .buffer = greenBuffer,
2727 .usePremultipliedAlpha = true,
2728 },
2729 },
2730 .alpha = 1.0f,
2731 .sourceDataspace = dataspace,
2732 .whitePointNits = 200.f,
2733 };
2734
2735 const renderengine::LayerSettings redLayer{
2736 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2737 .source =
2738 renderengine::PixelSource{
2739 .buffer =
2740 renderengine::Buffer{
2741 .buffer = redBuffer,
2742 .usePremultipliedAlpha = true,
2743 },
2744 },
2745 .alpha = 1.0f,
2746 .sourceDataspace = dataspace,
2747 // When the white point is not set for a layer, just ignore it and treat it as the same
2748 // as the max layer
2749 .whitePointNits = -1.f,
2750 };
2751
2752 std::vector<renderengine::LayerSettings> layers{greenLayer, redLayer};
2753 invokeDraw(display, layers);
2754
2755 expectBufferColor(Rect(1, 1), 0, 0, 0, 255, 1);
2756 expectBufferColor(Rect(1, 0, 2, 1), 0, 122, 0, 255, 1);
2757}
2758
2759TEST_P(RenderEngineTest, testDimming_inGammaSpace_withDisplayColorTransform_deviceHandles) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002760 if (!GetParam()->typeSupported()) {
2761 GTEST_SKIP();
2762 }
Alec Mouri9bcd1d12022-04-21 22:16:56 +00002763 initializeRenderEngine();
2764
2765 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2766 ui::Dataspace::TRANSFER_GAMMA2_2 |
2767 ui::Dataspace::RANGE_FULL);
2768
2769 const auto displayRect = Rect(3, 1);
2770 const renderengine::DisplaySettings display{
2771 .physicalDisplay = displayRect,
2772 .clip = displayRect,
2773 .outputDataspace = dataspace,
2774 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
2775 .deviceHandlesColorTransform = true,
2776 .targetLuminanceNits = 1000.f,
2777 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2778 };
2779
2780 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2781 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2782 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2783
2784 const renderengine::LayerSettings greenLayer{
2785 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2786 .source =
2787 renderengine::PixelSource{
2788 .buffer =
2789 renderengine::Buffer{
2790 .buffer = greenBuffer,
2791 .usePremultipliedAlpha = true,
2792 },
2793 },
2794 .alpha = 1.0f,
2795 .sourceDataspace = dataspace,
2796 .whitePointNits = 200.f,
2797 };
2798
2799 const renderengine::LayerSettings redLayer{
2800 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2801 .source =
2802 renderengine::PixelSource{
2803 .buffer =
2804 renderengine::Buffer{
2805 .buffer = redBuffer,
2806 .usePremultipliedAlpha = true,
2807 },
2808 },
2809 .alpha = 1.0f,
2810 .sourceDataspace = dataspace,
2811 // When the white point is not set for a layer, just ignore it and treat it as the same
2812 // as the max layer
2813 .whitePointNits = -1.f,
2814 };
2815
2816 std::vector<renderengine::LayerSettings> layers{greenLayer, redLayer};
2817 invokeDraw(display, layers);
2818
2819 expectBufferColor(Rect(1, 1), 0, 122, 0, 255, 1);
2820 expectBufferColor(Rect(1, 0, 2, 1), 122, 0, 0, 255, 1);
2821}
2822
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002823TEST_P(RenderEngineTest, testDimming_withoutTargetLuminance) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002824 if (!GetParam()->typeSupported()) {
2825 GTEST_SKIP();
2826 }
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002827 initializeRenderEngine();
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002828
2829 const auto displayRect = Rect(2, 1);
2830 const renderengine::DisplaySettings display{
2831 .physicalDisplay = displayRect,
2832 .clip = displayRect,
2833 .outputDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2834 .targetLuminanceNits = -1.f,
2835 };
2836
2837 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2838 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2839
2840 const renderengine::LayerSettings greenLayer{
2841 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2842 .source =
2843 renderengine::PixelSource{
2844 .buffer =
2845 renderengine::Buffer{
2846 .buffer = greenBuffer,
2847 .usePremultipliedAlpha = true,
2848 },
2849 },
2850 .alpha = 1.0f,
2851 .sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2852 .whitePointNits = 200.f,
2853 };
2854
2855 const renderengine::LayerSettings blueLayer{
2856 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2857 .source =
2858 renderengine::PixelSource{
2859 .buffer =
2860 renderengine::Buffer{
2861 .buffer = blueBuffer,
2862 .usePremultipliedAlpha = true,
2863 },
2864 },
2865 .alpha = 1.0f,
2866 .sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2867 .whitePointNits = 1000.f,
2868 };
2869
2870 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer};
2871 invokeDraw(display, layers);
2872
2873 expectBufferColor(Rect(1, 1), 0, 51, 0, 255, 1);
2874 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 255, 255);
2875}
2876
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002877TEST_P(RenderEngineTest, test_isOpaque) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002878 if (!GetParam()->typeSupported()) {
2879 GTEST_SKIP();
2880 }
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002881 initializeRenderEngine();
2882
2883 const auto rect = Rect(0, 0, 1, 1);
2884 const renderengine::DisplaySettings display{
2885 .physicalDisplay = rect,
2886 .clip = rect,
2887 .outputDataspace = ui::Dataspace::DISPLAY_P3,
2888 };
2889
2890 // Create an unpremul buffer that is green with no alpha. Using isOpaque
2891 // should make the green show.
2892 const auto buf = allocateSourceBuffer(1, 1);
2893 {
2894 uint8_t* pixels;
2895 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2896 reinterpret_cast<void**>(&pixels));
2897 pixels[0] = 0;
2898 pixels[1] = 255;
2899 pixels[2] = 0;
2900 pixels[3] = 0;
2901 buf->getBuffer()->unlock();
2902 }
2903
2904 const renderengine::LayerSettings greenLayer{
2905 .geometry.boundaries = rect.toFloatRect(),
2906 .source =
2907 renderengine::PixelSource{
2908 .buffer =
2909 renderengine::Buffer{
2910 .buffer = buf,
2911 // Although the pixels are not
2912 // premultiplied in practice, this
2913 // matches the input we see.
2914 .usePremultipliedAlpha = true,
2915 .isOpaque = true,
2916 },
2917 },
2918 .alpha = 1.0f,
2919 };
2920
Sally Qi59a9f502021-10-12 18:53:23 +00002921 std::vector<renderengine::LayerSettings> layers{greenLayer};
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002922 invokeDraw(display, layers);
2923
Alec Mouri47bcb072023-08-15 02:02:49 +00002924 expectBufferColor(rect, 117, 251, 76, 255);
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002925}
Alec Mouri4049b532021-10-15 20:59:33 -07002926
Alec Mouri4049b532021-10-15 20:59:33 -07002927TEST_P(RenderEngineTest, test_tonemapPQMatches) {
Alec Mouri47bcb072023-08-15 02:02:49 +00002928 if (!GetParam()->typeSupported()) {
Alec Mouri5a493722022-01-26 16:43:02 -08002929 GTEST_SKIP();
Alec Mouri4049b532021-10-15 20:59:33 -07002930 }
2931
Alec Mouri4049b532021-10-15 20:59:33 -07002932 initializeRenderEngine();
2933
Alec Mouri5a493722022-01-26 16:43:02 -08002934 tonemap(
2935 static_cast<ui::Dataspace>(HAL_DATASPACE_STANDARD_BT2020 |
2936 HAL_DATASPACE_TRANSFER_ST2084 | HAL_DATASPACE_RANGE_FULL),
2937 [](vec3 color) { return EOTF_PQ(color); },
2938 [](vec3 color, float) {
2939 static constexpr float kMaxPQLuminance = 10000.f;
2940 return color * kMaxPQLuminance;
2941 });
2942}
Alec Mouri4049b532021-10-15 20:59:33 -07002943
Alec Mouri5a493722022-01-26 16:43:02 -08002944TEST_P(RenderEngineTest, test_tonemapHLGMatches) {
Alec Mouri47bcb072023-08-15 02:02:49 +00002945 if (!GetParam()->typeSupported()) {
Alec Mouri5a493722022-01-26 16:43:02 -08002946 GTEST_SKIP();
Alec Mouri4049b532021-10-15 20:59:33 -07002947 }
2948
Alec Mouri5a493722022-01-26 16:43:02 -08002949 initializeRenderEngine();
Alec Mouri4049b532021-10-15 20:59:33 -07002950
Alec Mouri5a493722022-01-26 16:43:02 -08002951 tonemap(
2952 static_cast<ui::Dataspace>(HAL_DATASPACE_STANDARD_BT2020 | HAL_DATASPACE_TRANSFER_HLG |
2953 HAL_DATASPACE_RANGE_FULL),
2954 [](vec3 color) { return EOTF_HLG(color); },
2955 [](vec3 color, float currentLuminaceNits) {
2956 static constexpr float kMaxHLGLuminance = 1000.f;
Alec Mouri7a577452022-03-04 23:41:38 +00002957 return color * kMaxHLGLuminance;
Alec Mouri5a493722022-01-26 16:43:02 -08002958 });
Alec Mouri4049b532021-10-15 20:59:33 -07002959}
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -05002960
2961TEST_P(RenderEngineTest, r8_behaves_as_mask) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002962 if (!GetParam()->typeSupported()) {
2963 GTEST_SKIP();
2964 }
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -05002965 initializeRenderEngine();
2966
2967 const auto r8Buffer = allocateR8Buffer(2, 1);
2968 if (!r8Buffer) {
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05002969 GTEST_SKIP() << "Test is only necessary on devices that support r8";
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -05002970 return;
2971 }
2972 {
2973 uint8_t* pixels;
2974 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2975 reinterpret_cast<void**>(&pixels));
2976 // This will be drawn on top of a green buffer. We'll verify that 255
2977 // results in keeping the original green and 0 results in black.
2978 pixels[0] = 0;
2979 pixels[1] = 255;
2980 r8Buffer->getBuffer()->unlock();
2981 }
2982
2983 const auto rect = Rect(0, 0, 2, 1);
2984 const renderengine::DisplaySettings display{
2985 .physicalDisplay = rect,
2986 .clip = rect,
2987 .outputDataspace = ui::Dataspace::SRGB,
2988 };
2989
2990 const auto greenBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(0, 255, 0, 255));
2991 const renderengine::LayerSettings greenLayer{
2992 .geometry.boundaries = rect.toFloatRect(),
2993 .source =
2994 renderengine::PixelSource{
2995 .buffer =
2996 renderengine::Buffer{
2997 .buffer = greenBuffer,
2998 },
2999 },
3000 .alpha = 1.0f,
3001 };
3002 const renderengine::LayerSettings r8Layer{
3003 .geometry.boundaries = rect.toFloatRect(),
3004 .source =
3005 renderengine::PixelSource{
3006 .buffer =
3007 renderengine::Buffer{
3008 .buffer = r8Buffer,
3009 },
3010 },
3011 .alpha = 1.0f,
3012 };
3013
3014 std::vector<renderengine::LayerSettings> layers{greenLayer, r8Layer};
3015 invokeDraw(display, layers);
3016
3017 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 255);
3018 expectBufferColor(Rect(1, 0, 2, 1), 0, 255, 0, 255);
3019}
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003020
3021TEST_P(RenderEngineTest, r8_respects_color_transform) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003022 if (!GetParam()->typeSupported()) {
3023 GTEST_SKIP();
3024 }
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003025 initializeRenderEngine();
3026
3027 const auto r8Buffer = allocateR8Buffer(2, 1);
3028 if (!r8Buffer) {
3029 GTEST_SKIP() << "Test is only necessary on devices that support r8";
3030 return;
3031 }
3032 {
3033 uint8_t* pixels;
3034 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
3035 reinterpret_cast<void**>(&pixels));
3036 pixels[0] = 0;
3037 pixels[1] = 255;
3038 r8Buffer->getBuffer()->unlock();
3039 }
3040
3041 const auto rect = Rect(0, 0, 2, 1);
3042 const renderengine::DisplaySettings display{
3043 .physicalDisplay = rect,
3044 .clip = rect,
3045 .outputDataspace = ui::Dataspace::SRGB,
3046 // Verify that the R8 layer respects the color transform when
3047 // deviceHandlesColorTransform is false. This transform converts
3048 // pure red to pure green. That will occur when the R8 buffer is
3049 // 255. When the R8 buffer is 0, it will still change to black, as
3050 // with r8_behaves_as_mask.
Alec Mouri9bcd1d12022-04-21 22:16:56 +00003051 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003052 .deviceHandlesColorTransform = false,
3053 };
3054
3055 const auto redBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(255, 0, 0, 255));
3056 const renderengine::LayerSettings redLayer{
3057 .geometry.boundaries = rect.toFloatRect(),
3058 .source =
3059 renderengine::PixelSource{
3060 .buffer =
3061 renderengine::Buffer{
3062 .buffer = redBuffer,
3063 },
3064 },
3065 .alpha = 1.0f,
3066 };
3067 const renderengine::LayerSettings r8Layer{
3068 .geometry.boundaries = rect.toFloatRect(),
3069 .source =
3070 renderengine::PixelSource{
3071 .buffer =
3072 renderengine::Buffer{
3073 .buffer = r8Buffer,
3074 },
3075 },
3076 .alpha = 1.0f,
3077 };
3078
3079 std::vector<renderengine::LayerSettings> layers{redLayer, r8Layer};
3080 invokeDraw(display, layers);
3081
3082 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 255);
3083 expectBufferColor(Rect(1, 0, 2, 1), 0, 255, 0, 255);
3084}
3085
3086TEST_P(RenderEngineTest, r8_respects_color_transform_when_device_handles) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003087 if (!GetParam()->typeSupported()) {
3088 GTEST_SKIP();
3089 }
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003090 initializeRenderEngine();
3091
3092 const auto r8Buffer = allocateR8Buffer(2, 1);
3093 if (!r8Buffer) {
3094 GTEST_SKIP() << "Test is only necessary on devices that support r8";
3095 return;
3096 }
3097 {
3098 uint8_t* pixels;
3099 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
3100 reinterpret_cast<void**>(&pixels));
3101 pixels[0] = 0;
3102 pixels[1] = 255;
3103 r8Buffer->getBuffer()->unlock();
3104 }
3105
3106 const auto rect = Rect(0, 0, 2, 1);
3107 const renderengine::DisplaySettings display{
3108 .physicalDisplay = rect,
3109 .clip = rect,
3110 .outputDataspace = ui::Dataspace::SRGB,
3111 // If deviceHandlesColorTransform is true, pixels where the A8
3112 // buffer is opaque are unaffected. If the colorTransform is
3113 // invertible, pixels where the A8 buffer are transparent have the
3114 // inverse applied to them so that the DPU will convert them back to
3115 // black. Test with an arbitrary, invertible matrix.
3116 .colorTransform = mat4(1, 0, 0, 2,
3117 3, 1, 2, 5,
3118 0, 5, 3, 0,
3119 0, 1, 0, 2),
3120 .deviceHandlesColorTransform = true,
3121 };
3122
3123 const auto redBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(255, 0, 0, 255));
3124 const renderengine::LayerSettings redLayer{
3125 .geometry.boundaries = rect.toFloatRect(),
3126 .source =
3127 renderengine::PixelSource{
3128 .buffer =
3129 renderengine::Buffer{
3130 .buffer = redBuffer,
3131 },
3132 },
3133 .alpha = 1.0f,
3134 };
3135 const renderengine::LayerSettings r8Layer{
3136 .geometry.boundaries = rect.toFloatRect(),
3137 .source =
3138 renderengine::PixelSource{
3139 .buffer =
3140 renderengine::Buffer{
3141 .buffer = r8Buffer,
3142 },
3143 },
3144 .alpha = 1.0f,
3145 };
3146
3147 std::vector<renderengine::LayerSettings> layers{redLayer, r8Layer};
3148 invokeDraw(display, layers);
3149
3150 expectBufferColor(Rect(1, 0, 2, 1), 255, 0, 0, 255); // Still red.
3151 expectBufferColor(Rect(0, 0, 1, 1), 0, 70, 0, 255);
3152}
Leon Scroggins III45be9182022-04-27 10:37:11 -04003153
3154TEST_P(RenderEngineTest, primeShaderCache) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003155 if (!GetParam()->typeSupported()) {
3156 GTEST_SKIP();
3157 }
Leon Scroggins III45be9182022-04-27 10:37:11 -04003158 initializeRenderEngine();
3159
Bruno BELANYIb9b5b702023-10-13 13:25:11 +00003160 auto fut = mRE->primeCache(false);
Leon Scroggins III45be9182022-04-27 10:37:11 -04003161 if (fut.valid()) {
3162 fut.wait();
3163 }
3164
Alec Mouri47bcb072023-08-15 02:02:49 +00003165 static constexpr int kMinimumExpectedShadersCompiled = 60;
Leon Scroggins III45be9182022-04-27 10:37:11 -04003166 ASSERT_GT(static_cast<skia::SkiaGLRenderEngine*>(mRE.get())->reportShadersCompiled(),
Alec Mouri47bcb072023-08-15 02:02:49 +00003167 kMinimumExpectedShadersCompiled);
Leon Scroggins III45be9182022-04-27 10:37:11 -04003168}
Derek Sollenbergerd3f60652021-06-11 15:34:36 -04003169} // namespace renderengine
Alec Mouri6e57f682018-09-29 20:45:08 -07003170} // namespace android
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08003171
3172// TODO(b/129481165): remove the #pragma below and fix conversion issues
Marin Shalamanovbed7fd32020-12-21 20:02:20 +01003173#pragma clang diagnostic pop // ignored "-Wconversion -Wextra"