blob: 4e5440f5aeb97954a2f35e2cdda8755feee95df4 [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;
Leon Scroggins III696bf932024-01-24 15:21:05 -0500109 virtual renderengine::RenderEngine::GraphicsApi graphicsApi() = 0;
Nolan Scobie195631a2024-03-26 12:22:23 -0400110 virtual renderengine::RenderEngine::SkiaBackend skiaBackend() = 0;
Leon Scroggins IIIf3369ed2024-02-16 17:52:42 -0500111 bool apiSupported() { return renderengine::RenderEngine::canSupport(graphicsApi()); }
Leon Scroggins III5ef55002024-01-25 10:51:45 -0500112 std::unique_ptr<renderengine::RenderEngine> createRenderEngine() {
113 renderengine::RenderEngineCreationArgs reCreationArgs =
114 renderengine::RenderEngineCreationArgs::Builder()
115 .setPixelFormat(static_cast<int>(ui::PixelFormat::RGBA_8888))
116 .setImageCacheSize(1)
117 .setEnableProtectedContext(false)
118 .setPrecacheToneMapperShaderOnly(false)
119 .setSupportsBackgroundBlur(true)
120 .setContextPriority(renderengine::RenderEngine::ContextPriority::MEDIUM)
Leon Scroggins III696bf932024-01-24 15:21:05 -0500121 .setThreaded(renderengine::RenderEngine::Threaded::NO)
122 .setGraphicsApi(graphicsApi())
Nolan Scobie195631a2024-03-26 12:22:23 -0400123 .setSkiaBackend(skiaBackend())
Leon Scroggins III5ef55002024-01-25 10:51:45 -0500124 .build();
125 return renderengine::RenderEngine::create(reCreationArgs);
126 }
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800127};
128
Alec Mouri0eab3e82020-12-08 18:10:27 -0800129class SkiaGLESRenderEngineFactory : public RenderEngineFactory {
130public:
Alec Mouric0aae732021-01-12 13:32:18 -0800131 std::string name() override { return "SkiaGLRenderEngineFactory"; }
Alec Mouri0eab3e82020-12-08 18:10:27 -0800132
Leon Scroggins III696bf932024-01-24 15:21:05 -0500133 renderengine::RenderEngine::GraphicsApi graphicsApi() {
134 return renderengine::RenderEngine::GraphicsApi::GL;
Alec Mouric0aae732021-01-12 13:32:18 -0800135 }
Nolan Scobie195631a2024-03-26 12:22:23 -0400136
137 renderengine::RenderEngine::SkiaBackend skiaBackend() override {
138 return renderengine::RenderEngine::SkiaBackend::GANESH;
139 }
140};
141
142class GaneshVkRenderEngineFactory : public RenderEngineFactory {
143public:
144 std::string name() override { return "GaneshVkRenderEngineFactory"; }
145
146 renderengine::RenderEngine::GraphicsApi graphicsApi() override {
147 return renderengine::RenderEngine::GraphicsApi::VK;
148 }
149
150 renderengine::RenderEngine::SkiaBackend skiaBackend() override {
151 return renderengine::RenderEngine::SkiaBackend::GANESH;
152 }
153};
154
155class GraphiteVkRenderEngineFactory : public RenderEngineFactory {
156public:
157 std::string name() override { return "GraphiteVkRenderEngineFactory"; }
158
159 renderengine::RenderEngine::GraphicsApi graphicsApi() override {
160 return renderengine::RenderEngine::GraphicsApi::VK;
161 }
162
163 renderengine::RenderEngine::SkiaBackend skiaBackend() override {
164 return renderengine::RenderEngine::SkiaBackend::GRAPHITE;
165 }
Alec Mouri0eab3e82020-12-08 18:10:27 -0800166};
167
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800168class RenderEngineTest : public ::testing::TestWithParam<std::shared_ptr<RenderEngineFactory>> {
169public:
Alec Mouria90a5702021-04-16 16:36:21 +0000170 std::shared_ptr<renderengine::ExternalTexture> allocateDefaultBuffer() {
171 return std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800172 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -0700173 ExternalTexture>(sp<GraphicBuffer>::
174 make(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT,
175 HAL_PIXEL_FORMAT_RGBA_8888, 1,
176 GRALLOC_USAGE_SW_READ_OFTEN |
177 GRALLOC_USAGE_SW_WRITE_OFTEN |
178 GRALLOC_USAGE_HW_RENDER |
179 GRALLOC_USAGE_HW_TEXTURE,
180 "output"),
Alec Mouria90a5702021-04-16 16:36:21 +0000181 *mRE,
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800182 renderengine::impl::ExternalTexture::Usage::READABLE |
183 renderengine::impl::ExternalTexture::Usage::
184 WRITEABLE);
Alec Mouri6e57f682018-09-29 20:45:08 -0700185 }
186
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800187 // Allocates a 1x1 buffer to fill with a solid color
Alec Mouria90a5702021-04-16 16:36:21 +0000188 std::shared_ptr<renderengine::ExternalTexture> allocateSourceBuffer(uint32_t width,
189 uint32_t height) {
190 return std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800191 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -0700192 ExternalTexture>(sp<GraphicBuffer>::
193 make(width, height, HAL_PIXEL_FORMAT_RGBA_8888, 1,
194 GRALLOC_USAGE_SW_READ_OFTEN |
195 GRALLOC_USAGE_SW_WRITE_OFTEN |
196 GRALLOC_USAGE_HW_TEXTURE,
197 "input"),
Alec Mouria90a5702021-04-16 16:36:21 +0000198 *mRE,
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800199 renderengine::impl::ExternalTexture::Usage::READABLE |
200 renderengine::impl::ExternalTexture::Usage::
201 WRITEABLE);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800202 }
203
Alec Mouricdf6cbc2021-11-01 17:21:15 -0700204 std::shared_ptr<renderengine::ExternalTexture> allocateAndFillSourceBuffer(uint32_t width,
205 uint32_t height,
206 ubyte4 color) {
207 const auto buffer = allocateSourceBuffer(width, height);
208 uint8_t* pixels;
209 buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
210 reinterpret_cast<void**>(&pixels));
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -0500211 for (uint32_t j = 0; j < height; j++) {
212 uint8_t* dst = pixels + (buffer->getBuffer()->getStride() * j * 4);
213 for (uint32_t i = 0; i < width; i++) {
214 dst[0] = color.r;
215 dst[1] = color.g;
216 dst[2] = color.b;
217 dst[3] = color.a;
218 dst += 4;
219 }
220 }
Alec Mouricdf6cbc2021-11-01 17:21:15 -0700221 buffer->getBuffer()->unlock();
222 return buffer;
223 }
224
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -0500225 std::shared_ptr<renderengine::ExternalTexture> allocateR8Buffer(int width, int height) {
Ady Abrahamd11bade2022-08-01 16:18:03 -0700226 const auto kUsageFlags =
227 static_cast<uint64_t>(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
228 GRALLOC_USAGE_HW_TEXTURE);
229 auto buffer =
230 sp<GraphicBuffer>::make(static_cast<uint32_t>(width), static_cast<uint32_t>(height),
231 android::PIXEL_FORMAT_R_8, 1u, kUsageFlags, "r8");
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -0500232 if (buffer->initCheck() != 0) {
233 // Devices are not required to support R8.
234 return nullptr;
235 }
236 return std::make_shared<
237 renderengine::impl::ExternalTexture>(std::move(buffer), *mRE,
238 renderengine::impl::ExternalTexture::Usage::
239 READABLE);
240 }
241
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800242 RenderEngineTest() {
243 const ::testing::TestInfo* const test_info =
244 ::testing::UnitTest::GetInstance()->current_test_info();
245 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800246 }
Alec Mouri1089aed2018-10-25 21:33:57 -0700247
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800248 ~RenderEngineTest() {
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800249 if (WRITE_BUFFER_TO_FILE_ON_FAILURE && ::testing::Test::HasFailure()) {
250 writeBufferToFile("/data/texture_out_");
251 }
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800252 const ::testing::TestInfo* const test_info =
253 ::testing::UnitTest::GetInstance()->current_test_info();
254 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800255 }
256
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800257 void writeBufferToFile(const char* basename) {
258 std::string filename(basename);
259 filename.append(::testing::UnitTest::GetInstance()->current_test_info()->name());
260 filename.append(".ppm");
261 std::ofstream file(filename.c_str(), std::ios::binary);
262 if (!file.is_open()) {
263 ALOGE("Unable to open file: %s", filename.c_str());
264 ALOGE("You may need to do: \"adb shell setenforce 0\" to enable "
265 "surfaceflinger to write debug images");
266 return;
267 }
268
Alec Mouri1089aed2018-10-25 21:33:57 -0700269 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +0000270 mBuffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
271 reinterpret_cast<void**>(&pixels));
Alec Mouri1089aed2018-10-25 21:33:57 -0700272
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800273 file << "P6\n";
Alec Mouria90a5702021-04-16 16:36:21 +0000274 file << mBuffer->getBuffer()->getWidth() << "\n";
275 file << mBuffer->getBuffer()->getHeight() << "\n";
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800276 file << 255 << "\n";
277
Alec Mouria90a5702021-04-16 16:36:21 +0000278 std::vector<uint8_t> outBuffer(mBuffer->getBuffer()->getWidth() *
279 mBuffer->getBuffer()->getHeight() * 3);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800280 auto outPtr = reinterpret_cast<uint8_t*>(outBuffer.data());
281
Alec Mouria90a5702021-04-16 16:36:21 +0000282 for (int32_t j = 0; j < mBuffer->getBuffer()->getHeight(); j++) {
283 const uint8_t* src = pixels + (mBuffer->getBuffer()->getStride() * j) * 4;
284 for (int32_t i = 0; i < mBuffer->getBuffer()->getWidth(); i++) {
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800285 // Only copy R, G and B components
286 outPtr[0] = src[0];
287 outPtr[1] = src[1];
288 outPtr[2] = src[2];
289 outPtr += 3;
290
291 src += 4;
292 }
293 }
294 file.write(reinterpret_cast<char*>(outBuffer.data()), outBuffer.size());
Alec Mouria90a5702021-04-16 16:36:21 +0000295 mBuffer->getBuffer()->unlock();
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800296 }
297
298 void expectBufferColor(const Region& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
299 size_t c;
300 Rect const* rect = region.getArray(&c);
301 for (size_t i = 0; i < c; i++, rect++) {
302 expectBufferColor(*rect, r, g, b, a);
303 }
304 }
305
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -0400306 void expectBufferColor(const Point& point, uint8_t r, uint8_t g, uint8_t b, uint8_t a,
307 uint8_t tolerance = 0) {
308 expectBufferColor(Rect(point.x, point.y, point.x + 1, point.y + 1), r, g, b, a, tolerance);
309 }
310
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800311 void expectBufferColor(const Rect& rect, uint8_t r, uint8_t g, uint8_t b, uint8_t a,
312 uint8_t tolerance = 0) {
Alec Mouri4049b532021-10-15 20:59:33 -0700313 auto generator = [=](Point) { return ubyte4(r, g, b, a); };
314 expectBufferColor(rect, generator, tolerance);
315 }
316
317 using ColorGenerator = std::function<ubyte4(Point location)>;
318
319 void expectBufferColor(const Rect& rect, ColorGenerator generator, uint8_t tolerance = 0) {
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800320 auto colorCompare = [tolerance](const uint8_t* colorA, const uint8_t* colorB) {
321 auto colorBitCompare = [tolerance](uint8_t a, uint8_t b) {
322 uint8_t tmp = a >= b ? a - b : b - a;
323 return tmp <= tolerance;
324 };
325 return std::equal(colorA, colorA + 4, colorB, colorBitCompare);
Alec Mouri1089aed2018-10-25 21:33:57 -0700326 };
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800327
Alec Mouri4049b532021-10-15 20:59:33 -0700328 expectBufferColor(rect, generator, colorCompare);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800329 }
330
Alec Mouri4049b532021-10-15 20:59:33 -0700331 void expectBufferColor(const Rect& region, ColorGenerator generator,
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800332 std::function<bool(const uint8_t* a, const uint8_t* b)> colorCompare) {
333 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +0000334 mBuffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
335 reinterpret_cast<void**>(&pixels));
Alec Mouri1089aed2018-10-25 21:33:57 -0700336 int32_t maxFails = 10;
337 int32_t fails = 0;
338 for (int32_t j = 0; j < region.getHeight(); j++) {
Alec Mouria90a5702021-04-16 16:36:21 +0000339 const uint8_t* src = pixels +
340 (mBuffer->getBuffer()->getStride() * (region.top + j) + region.left) * 4;
Alec Mouri1089aed2018-10-25 21:33:57 -0700341 for (int32_t i = 0; i < region.getWidth(); i++) {
Alec Mouri4049b532021-10-15 20:59:33 -0700342 const auto location = Point(region.left + i, region.top + j);
343 const ubyte4 colors = generator(location);
344 const uint8_t expected[4] = {colors.r, colors.g, colors.b, colors.a};
345 bool colorMatches = colorCompare(src, expected);
346 EXPECT_TRUE(colorMatches)
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -0400347 << GetParam()->name().c_str() << ": "
Alec Mouri4049b532021-10-15 20:59:33 -0700348 << "pixel @ (" << location.x << ", " << location.y << "): "
349 << "expected (" << static_cast<uint32_t>(colors.r) << ", "
350 << static_cast<uint32_t>(colors.g) << ", "
351 << static_cast<uint32_t>(colors.b) << ", "
352 << static_cast<uint32_t>(colors.a) << "), "
Alec Mouri1089aed2018-10-25 21:33:57 -0700353 << "got (" << static_cast<uint32_t>(src[0]) << ", "
354 << static_cast<uint32_t>(src[1]) << ", " << static_cast<uint32_t>(src[2])
355 << ", " << static_cast<uint32_t>(src[3]) << ")";
356 src += 4;
Alec Mouri4049b532021-10-15 20:59:33 -0700357 if (!colorMatches && ++fails >= maxFails) {
Alec Mouri1089aed2018-10-25 21:33:57 -0700358 break;
359 }
360 }
361 if (fails >= maxFails) {
362 break;
363 }
364 }
Alec Mouria90a5702021-04-16 16:36:21 +0000365 mBuffer->getBuffer()->unlock();
Alec Mouri1089aed2018-10-25 21:33:57 -0700366 }
367
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800368 void expectAlpha(const Rect& rect, uint8_t a) {
Alec Mouri4049b532021-10-15 20:59:33 -0700369 auto generator = [=](Point) { return ubyte4(0, 0, 0, a); };
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800370 auto colorCompare = [](const uint8_t* colorA, const uint8_t* colorB) {
371 return colorA[3] == colorB[3];
372 };
Alec Mouri4049b532021-10-15 20:59:33 -0700373 expectBufferColor(rect, generator, colorCompare);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800374 }
375
376 void expectShadowColor(const renderengine::LayerSettings& castingLayer,
Vishnu Naird9e4f462023-10-06 04:05:45 +0000377 const ShadowSettings& shadow, const ubyte4& casterColor,
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800378 const ubyte4& backgroundColor) {
379 const Rect casterRect(castingLayer.geometry.boundaries);
380 Region casterRegion = Region(casterRect);
Vishnu Nair50c0afe2022-07-11 15:04:07 -0700381 const float casterCornerRadius = (castingLayer.geometry.roundedCornersRadius.x +
382 castingLayer.geometry.roundedCornersRadius.y) /
383 2.0;
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800384 if (casterCornerRadius > 0.0f) {
385 // ignore the corners if a corner radius is set
386 Rect cornerRect(casterCornerRadius, casterCornerRadius);
387 casterRegion.subtractSelf(cornerRect.offsetTo(casterRect.left, casterRect.top));
388 casterRegion.subtractSelf(
389 cornerRect.offsetTo(casterRect.right - casterCornerRadius, casterRect.top));
390 casterRegion.subtractSelf(
391 cornerRect.offsetTo(casterRect.left, casterRect.bottom - casterCornerRadius));
392 casterRegion.subtractSelf(cornerRect.offsetTo(casterRect.right - casterCornerRadius,
393 casterRect.bottom - casterCornerRadius));
394 }
395
396 const float shadowInset = shadow.length * -1.0f;
397 const Rect casterWithShadow =
398 Rect(casterRect).inset(shadowInset, shadowInset, shadowInset, shadowInset);
399 const Region shadowRegion = Region(casterWithShadow).subtractSelf(casterRect);
400 const Region backgroundRegion = Region(fullscreenRect()).subtractSelf(casterWithShadow);
401
402 // verify casting layer
403 expectBufferColor(casterRegion, casterColor.r, casterColor.g, casterColor.b, casterColor.a);
404
405 // verify shadows by testing just the alpha since its difficult to validate the shadow color
406 size_t c;
407 Rect const* r = shadowRegion.getArray(&c);
408 for (size_t i = 0; i < c; i++, r++) {
409 expectAlpha(*r, 255);
410 }
411
412 // verify background
413 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
414 backgroundColor.a);
415 }
416
Vishnu Naird9e4f462023-10-06 04:05:45 +0000417 void expectShadowColorWithoutCaster(const FloatRect& casterBounds, const ShadowSettings& shadow,
Alec Mouribd17b3b2020-12-17 11:08:30 -0800418 const ubyte4& backgroundColor) {
419 const float shadowInset = shadow.length * -1.0f;
420 const Rect casterRect(casterBounds);
421 const Rect shadowRect =
422 Rect(casterRect).inset(shadowInset, shadowInset, shadowInset, shadowInset);
423
424 const Region backgroundRegion =
425 Region(fullscreenRect()).subtractSelf(casterRect).subtractSelf(shadowRect);
426
427 expectAlpha(shadowRect, 255);
428 // (0, 0, 0) fill on the bounds of the layer should be ignored.
429 expectBufferColor(casterRect, 255, 255, 255, 255, 254);
430
431 // verify background
432 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
433 backgroundColor.a);
434 }
435
Vishnu Naird9e4f462023-10-06 04:05:45 +0000436 static ShadowSettings getShadowSettings(const vec2& casterPos, float shadowLength,
437 bool casterIsTranslucent) {
438 ShadowSettings shadow;
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800439 shadow.ambientColor = {0.0f, 0.0f, 0.0f, 0.039f};
440 shadow.spotColor = {0.0f, 0.0f, 0.0f, 0.19f};
441 shadow.lightPos = vec3(casterPos.x, casterPos.y, 0);
442 shadow.lightRadius = 0.0f;
443 shadow.length = shadowLength;
444 shadow.casterIsTranslucent = casterIsTranslucent;
445 return shadow;
446 }
447
Alec Mouri1089aed2018-10-25 21:33:57 -0700448 static Rect fullscreenRect() { return Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT); }
449
450 static Rect offsetRect() {
451 return Rect(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_WIDTH,
452 DEFAULT_DISPLAY_HEIGHT);
453 }
454
455 static Rect offsetRectAtZero() {
456 return Rect(DEFAULT_DISPLAY_WIDTH - DEFAULT_DISPLAY_OFFSET,
457 DEFAULT_DISPLAY_HEIGHT - DEFAULT_DISPLAY_OFFSET);
458 }
459
Sally Qi59a9f502021-10-12 18:53:23 +0000460 void invokeDraw(const renderengine::DisplaySettings& settings,
461 const std::vector<renderengine::LayerSettings>& layers) {
Patrick Williams2e9748f2022-08-09 22:48:18 +0000462 ftl::Future<FenceResult> future =
Alec Mourif29700f2023-08-17 21:53:31 +0000463 mRE->drawLayers(settings, layers, mBuffer, base::unique_fd());
Patrick Williams2e9748f2022-08-09 22:48:18 +0000464 ASSERT_TRUE(future.valid());
Sally Qi59a9f502021-10-12 18:53:23 +0000465
Patrick Williams2e9748f2022-08-09 22:48:18 +0000466 auto result = future.get();
467 ASSERT_TRUE(result.ok());
Alec Mouri1089aed2018-10-25 21:33:57 -0700468
Patrick Williams2e9748f2022-08-09 22:48:18 +0000469 auto fence = result.value();
470 fence->waitForever(LOG_TAG);
Alec Mouri1089aed2018-10-25 21:33:57 -0700471 }
472
Alec Mourid43ccab2019-03-13 12:23:45 -0700473 void drawEmptyLayers() {
Alec Mouri6e57f682018-09-29 20:45:08 -0700474 renderengine::DisplaySettings settings;
Sally Qi59a9f502021-10-12 18:53:23 +0000475 std::vector<renderengine::LayerSettings> layers;
Alec Mouric0aae732021-01-12 13:32:18 -0800476 invokeDraw(settings, layers);
Alec Mouri6e57f682018-09-29 20:45:08 -0700477 }
478
Alec Mouri1089aed2018-10-25 21:33:57 -0700479 template <typename SourceVariant>
480 void fillBuffer(half r, half g, half b, half a);
481
482 template <typename SourceVariant>
483 void fillRedBuffer();
484
485 template <typename SourceVariant>
486 void fillGreenBuffer();
487
488 template <typename SourceVariant>
489 void fillBlueBuffer();
490
491 template <typename SourceVariant>
492 void fillRedTransparentBuffer();
493
494 template <typename SourceVariant>
495 void fillRedOffsetBuffer();
496
497 template <typename SourceVariant>
498 void fillBufferPhysicalOffset();
499
500 template <typename SourceVariant>
Alec Mouri5a6d8572020-03-23 23:56:15 -0700501 void fillBufferCheckers(uint32_t rotation);
Alec Mouri1089aed2018-10-25 21:33:57 -0700502
503 template <typename SourceVariant>
504 void fillBufferCheckersRotate0();
505
506 template <typename SourceVariant>
507 void fillBufferCheckersRotate90();
508
509 template <typename SourceVariant>
510 void fillBufferCheckersRotate180();
511
512 template <typename SourceVariant>
513 void fillBufferCheckersRotate270();
514
515 template <typename SourceVariant>
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800516 void fillBufferWithLayerTransform();
517
518 template <typename SourceVariant>
Alec Mouri1089aed2018-10-25 21:33:57 -0700519 void fillBufferLayerTransform();
520
521 template <typename SourceVariant>
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800522 void fillBufferWithColorTransform();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800523
524 template <typename SourceVariant>
Alec Mouri1089aed2018-10-25 21:33:57 -0700525 void fillBufferColorTransform();
526
Alec Mouri7c94edb2018-12-03 21:23:26 -0800527 template <typename SourceVariant>
Sally Qi2019fd22021-11-22 10:19:04 -0800528 void fillBufferWithColorTransformAndSourceDataspace(const ui::Dataspace sourceDataspace);
529
530 template <typename SourceVariant>
531 void fillBufferColorTransformAndSourceDataspace();
532
533 template <typename SourceVariant>
534 void fillBufferWithColorTransformAndOutputDataspace(const ui::Dataspace outputDataspace);
535
536 template <typename SourceVariant>
537 void fillBufferColorTransformAndOutputDataspace();
538
539 template <typename SourceVariant>
KaiChieh Chuangda2845c2020-12-14 16:49:38 +0800540 void fillBufferWithColorTransformZeroLayerAlpha();
541
542 template <typename SourceVariant>
543 void fillBufferColorTransformZeroLayerAlpha();
544
545 template <typename SourceVariant>
Alec Mouri7c94edb2018-12-03 21:23:26 -0800546 void fillRedBufferWithRoundedCorners();
547
548 template <typename SourceVariant>
549 void fillBufferWithRoundedCorners();
550
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000551 template <typename SourceVariant>
Lucas Dupin19c8f0e2019-11-25 17:55:44 -0800552 void fillBufferAndBlurBackground();
553
554 template <typename SourceVariant>
Alec Mourie8489fd2021-04-29 16:08:56 -0700555 void fillSmallLayerAndBlurBackground();
556
557 template <typename SourceVariant>
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000558 void overlayCorners();
559
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800560 void fillRedBufferTextureTransform();
561
562 void fillBufferTextureTransform();
563
564 void fillRedBufferWithPremultiplyAlpha();
565
566 void fillBufferWithPremultiplyAlpha();
567
568 void fillRedBufferWithoutPremultiplyAlpha();
569
570 void fillBufferWithoutPremultiplyAlpha();
571
Alec Mouriac335532018-11-12 15:01:33 -0800572 void fillGreenColorBufferThenClearRegion();
573
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800574 template <typename SourceVariant>
Vishnu Naird9e4f462023-10-06 04:05:45 +0000575 void drawShadow(const renderengine::LayerSettings& castingLayer, const ShadowSettings& shadow,
576 const ubyte4& casterColor, const ubyte4& backgroundColor);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800577
Vishnu Naird9e4f462023-10-06 04:05:45 +0000578 void drawShadowWithoutCaster(const FloatRect& castingBounds, const ShadowSettings& shadow,
Alec Mouribd17b3b2020-12-17 11:08:30 -0800579 const ubyte4& backgroundColor);
580
Alec Mouri5a493722022-01-26 16:43:02 -0800581 // Tonemaps grey values from sourceDataspace -> Display P3 and checks that GPU and CPU
582 // implementations are identical Also implicitly checks that the injected tonemap shader
583 // compiles
584 void tonemap(ui::Dataspace sourceDataspace, std::function<vec3(vec3)> eotf,
585 std::function<vec3(vec3, float)> scaleOotf);
586
Alec Mouric0aae732021-01-12 13:32:18 -0800587 void initializeRenderEngine();
588
589 std::unique_ptr<renderengine::RenderEngine> mRE;
Alec Mouria90a5702021-04-16 16:36:21 +0000590 std::shared_ptr<renderengine::ExternalTexture> mBuffer;
Alec Mouri6e57f682018-09-29 20:45:08 -0700591};
592
Alec Mouric0aae732021-01-12 13:32:18 -0800593void RenderEngineTest::initializeRenderEngine() {
594 const auto& renderEngineFactory = GetParam();
Alec Mouric16974e2022-09-13 17:35:48 +0000595 mRE = renderEngineFactory->createRenderEngine();
Alec Mouria90a5702021-04-16 16:36:21 +0000596 mBuffer = allocateDefaultBuffer();
Alec Mouric0aae732021-01-12 13:32:18 -0800597}
598
Alec Mouri1089aed2018-10-25 21:33:57 -0700599struct ColorSourceVariant {
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800600 static void fillColor(renderengine::LayerSettings& layer, half r, half g, half b,
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800601 RenderEngineTest* /*fixture*/) {
Alec Mouri1089aed2018-10-25 21:33:57 -0700602 layer.source.solidColor = half3(r, g, b);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800603 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700604 }
605};
606
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800607struct RelaxOpaqueBufferVariant {
608 static void setOpaqueBit(renderengine::LayerSettings& layer) {
609 layer.source.buffer.isOpaque = false;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800610 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800611 }
612
613 static uint8_t getAlphaChannel() { return 255; }
614};
615
616struct ForceOpaqueBufferVariant {
617 static void setOpaqueBit(renderengine::LayerSettings& layer) {
618 layer.source.buffer.isOpaque = true;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800619 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800620 }
621
622 static uint8_t getAlphaChannel() {
623 // The isOpaque bit will override the alpha channel, so this should be
624 // arbitrary.
Alec Mouric0aae732021-01-12 13:32:18 -0800625 return 50;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800626 }
627};
628
629template <typename OpaquenessVariant>
630struct BufferSourceVariant {
631 static void fillColor(renderengine::LayerSettings& layer, half r, half g, half b,
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800632 RenderEngineTest* fixture) {
Alec Mouria90a5702021-04-16 16:36:21 +0000633 const auto buf = fixture->allocateSourceBuffer(1, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800634
635 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +0000636 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
637 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800638
Alec Mouria90a5702021-04-16 16:36:21 +0000639 for (int32_t j = 0; j < buf->getBuffer()->getHeight(); j++) {
640 uint8_t* iter = pixels + (buf->getBuffer()->getStride() * j) * 4;
641 for (int32_t i = 0; i < buf->getBuffer()->getWidth(); i++) {
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800642 iter[0] = uint8_t(r * 255);
643 iter[1] = uint8_t(g * 255);
644 iter[2] = uint8_t(b * 255);
645 iter[3] = OpaquenessVariant::getAlphaChannel();
646 iter += 4;
647 }
648 }
649
Alec Mouria90a5702021-04-16 16:36:21 +0000650 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800651
652 layer.source.buffer.buffer = buf;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800653 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800654 OpaquenessVariant::setOpaqueBit(layer);
655 }
656};
657
Alec Mouri1089aed2018-10-25 21:33:57 -0700658template <typename SourceVariant>
659void RenderEngineTest::fillBuffer(half r, half g, half b, half a) {
660 renderengine::DisplaySettings settings;
661 settings.physicalDisplay = fullscreenRect();
662 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800663 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700664
Sally Qi59a9f502021-10-12 18:53:23 +0000665 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700666
667 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800668 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700669 layer.geometry.boundaries = fullscreenRect().toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800670 SourceVariant::fillColor(layer, r, g, b, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700671 layer.alpha = a;
672
Sally Qi59a9f502021-10-12 18:53:23 +0000673 layers.push_back(layer);
Alec Mouri1089aed2018-10-25 21:33:57 -0700674
Alec Mouric0aae732021-01-12 13:32:18 -0800675 invokeDraw(settings, layers);
Alec Mouri1089aed2018-10-25 21:33:57 -0700676}
677
678template <typename SourceVariant>
679void RenderEngineTest::fillRedBuffer() {
680 fillBuffer<SourceVariant>(1.0f, 0.0f, 0.0f, 1.0f);
681 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
682}
683
684template <typename SourceVariant>
685void RenderEngineTest::fillGreenBuffer() {
686 fillBuffer<SourceVariant>(0.0f, 1.0f, 0.0f, 1.0f);
687 expectBufferColor(fullscreenRect(), 0, 255, 0, 255);
688}
689
690template <typename SourceVariant>
691void RenderEngineTest::fillBlueBuffer() {
692 fillBuffer<SourceVariant>(0.0f, 0.0f, 1.0f, 1.0f);
693 expectBufferColor(fullscreenRect(), 0, 0, 255, 255);
694}
695
696template <typename SourceVariant>
697void RenderEngineTest::fillRedTransparentBuffer() {
698 fillBuffer<SourceVariant>(1.0f, 0.0f, 0.0f, .2f);
699 expectBufferColor(fullscreenRect(), 51, 0, 0, 51);
700}
701
702template <typename SourceVariant>
703void RenderEngineTest::fillRedOffsetBuffer() {
704 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800705 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700706 settings.physicalDisplay = offsetRect();
707 settings.clip = offsetRectAtZero();
708
Sally Qi59a9f502021-10-12 18:53:23 +0000709 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700710
711 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800712 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700713 layer.geometry.boundaries = offsetRectAtZero().toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800714 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700715 layer.alpha = 1.0f;
716
Sally Qi59a9f502021-10-12 18:53:23 +0000717 layers.push_back(layer);
Alec Mouric0aae732021-01-12 13:32:18 -0800718 invokeDraw(settings, layers);
Alec Mouri1089aed2018-10-25 21:33:57 -0700719}
720
721template <typename SourceVariant>
722void RenderEngineTest::fillBufferPhysicalOffset() {
723 fillRedOffsetBuffer<SourceVariant>();
724
725 expectBufferColor(Rect(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_WIDTH,
726 DEFAULT_DISPLAY_HEIGHT),
727 255, 0, 0, 255);
728 Rect offsetRegionLeft(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_HEIGHT);
729 Rect offsetRegionTop(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_OFFSET);
730
731 expectBufferColor(offsetRegionLeft, 0, 0, 0, 0);
732 expectBufferColor(offsetRegionTop, 0, 0, 0, 0);
733}
734
735template <typename SourceVariant>
Alec Mouri5a6d8572020-03-23 23:56:15 -0700736void RenderEngineTest::fillBufferCheckers(uint32_t orientationFlag) {
Alec Mouri1089aed2018-10-25 21:33:57 -0700737 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800738 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700739 settings.physicalDisplay = fullscreenRect();
740 // Here logical space is 2x2
741 settings.clip = Rect(2, 2);
Alec Mouri5a6d8572020-03-23 23:56:15 -0700742 settings.orientation = orientationFlag;
Alec Mouri1089aed2018-10-25 21:33:57 -0700743
Sally Qi59a9f502021-10-12 18:53:23 +0000744 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700745
746 renderengine::LayerSettings layerOne;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800747 layerOne.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700748 Rect rectOne(0, 0, 1, 1);
749 layerOne.geometry.boundaries = rectOne.toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800750 SourceVariant::fillColor(layerOne, 1.0f, 0.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700751 layerOne.alpha = 1.0f;
752
753 renderengine::LayerSettings layerTwo;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800754 layerTwo.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700755 Rect rectTwo(0, 1, 1, 2);
756 layerTwo.geometry.boundaries = rectTwo.toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800757 SourceVariant::fillColor(layerTwo, 0.0f, 1.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700758 layerTwo.alpha = 1.0f;
759
760 renderengine::LayerSettings layerThree;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800761 layerThree.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700762 Rect rectThree(1, 0, 2, 1);
763 layerThree.geometry.boundaries = rectThree.toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800764 SourceVariant::fillColor(layerThree, 0.0f, 0.0f, 1.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700765 layerThree.alpha = 1.0f;
766
Sally Qi59a9f502021-10-12 18:53:23 +0000767 layers.push_back(layerOne);
768 layers.push_back(layerTwo);
769 layers.push_back(layerThree);
Alec Mouri1089aed2018-10-25 21:33:57 -0700770
Alec Mouric0aae732021-01-12 13:32:18 -0800771 invokeDraw(settings, layers);
Alec Mouri1089aed2018-10-25 21:33:57 -0700772}
773
774template <typename SourceVariant>
775void RenderEngineTest::fillBufferCheckersRotate0() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700776 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_0);
Alec Mouri1089aed2018-10-25 21:33:57 -0700777 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0,
778 255);
779 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
780 DEFAULT_DISPLAY_HEIGHT / 2),
781 0, 0, 255, 255);
782 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
783 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
784 0, 0, 0, 0);
785 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
786 DEFAULT_DISPLAY_HEIGHT),
787 0, 255, 0, 255);
788}
789
790template <typename SourceVariant>
791void RenderEngineTest::fillBufferCheckersRotate90() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700792 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_90);
Alec Mouri1089aed2018-10-25 21:33:57 -0700793 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 255, 0,
794 255);
795 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
796 DEFAULT_DISPLAY_HEIGHT / 2),
797 255, 0, 0, 255);
798 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
799 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
800 0, 0, 255, 255);
801 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
802 DEFAULT_DISPLAY_HEIGHT),
803 0, 0, 0, 0);
804}
805
806template <typename SourceVariant>
807void RenderEngineTest::fillBufferCheckersRotate180() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700808 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_180);
Alec Mouri1089aed2018-10-25 21:33:57 -0700809 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 0,
810 0);
811 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
812 DEFAULT_DISPLAY_HEIGHT / 2),
813 0, 255, 0, 255);
814 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
815 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
816 255, 0, 0, 255);
817 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
818 DEFAULT_DISPLAY_HEIGHT),
819 0, 0, 255, 255);
820}
821
822template <typename SourceVariant>
823void RenderEngineTest::fillBufferCheckersRotate270() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700824 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_270);
Alec Mouri1089aed2018-10-25 21:33:57 -0700825 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 255,
826 255);
827 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
828 DEFAULT_DISPLAY_HEIGHT / 2),
829 0, 0, 0, 0);
830 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
831 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
832 0, 255, 0, 255);
833 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
834 DEFAULT_DISPLAY_HEIGHT),
835 255, 0, 0, 255);
836}
837
838template <typename SourceVariant>
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800839void RenderEngineTest::fillBufferWithLayerTransform() {
Alec Mouri1089aed2018-10-25 21:33:57 -0700840 renderengine::DisplaySettings settings;
841 settings.physicalDisplay = fullscreenRect();
842 // Here logical space is 2x2
843 settings.clip = Rect(2, 2);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800844 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700845
Sally Qi59a9f502021-10-12 18:53:23 +0000846 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700847
848 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800849 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700850 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
851 // Translate one pixel diagonally
852 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 -0800853 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700854 layer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
855 layer.alpha = 1.0f;
856
Sally Qi59a9f502021-10-12 18:53:23 +0000857 layers.push_back(layer);
Alec Mouri1089aed2018-10-25 21:33:57 -0700858
Alec Mouric0aae732021-01-12 13:32:18 -0800859 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800860}
Alec Mouri1089aed2018-10-25 21:33:57 -0700861
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800862template <typename SourceVariant>
863void RenderEngineTest::fillBufferLayerTransform() {
864 fillBufferWithLayerTransform<SourceVariant>();
Alec Mouri1089aed2018-10-25 21:33:57 -0700865 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 0, 0);
866 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
867 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
868 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
869 255, 0, 0, 255);
870}
871
872template <typename SourceVariant>
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800873void RenderEngineTest::fillBufferWithColorTransform() {
Alec Mouri1089aed2018-10-25 21:33:57 -0700874 renderengine::DisplaySettings settings;
875 settings.physicalDisplay = fullscreenRect();
876 settings.clip = Rect(1, 1);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800877 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700878
Sally Qi59a9f502021-10-12 18:53:23 +0000879 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700880
881 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800882 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700883 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800884 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700885 layer.alpha = 1.0f;
886
887 // construct a fake color matrix
888 // annihilate green and blue channels
KaiChieh Chuang436fc192020-09-07 13:48:42 +0800889 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
Alec Mouri1089aed2018-10-25 21:33:57 -0700890 // set red channel to red + green
891 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
892
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800893 layer.alpha = 1.0f;
894 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
895
Sally Qi59a9f502021-10-12 18:53:23 +0000896 layers.push_back(layer);
Alec Mouri1089aed2018-10-25 21:33:57 -0700897
Alec Mouric0aae732021-01-12 13:32:18 -0800898 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800899}
Alec Mouri1089aed2018-10-25 21:33:57 -0700900
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800901template <typename SourceVariant>
Sally Qi2019fd22021-11-22 10:19:04 -0800902void RenderEngineTest::fillBufferWithColorTransformAndSourceDataspace(
903 const ui::Dataspace sourceDataspace) {
904 renderengine::DisplaySettings settings;
905 settings.physicalDisplay = fullscreenRect();
906 settings.clip = Rect(1, 1);
907 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
908
909 std::vector<renderengine::LayerSettings> layers;
910
911 renderengine::LayerSettings layer;
Sally Qi2019fd22021-11-22 10:19:04 -0800912 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
913 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
Alec Mouric16974e2022-09-13 17:35:48 +0000914 layer.sourceDataspace = sourceDataspace;
Sally Qi2019fd22021-11-22 10:19:04 -0800915 layer.alpha = 1.0f;
916
917 // construct a fake color matrix
918 // annihilate green and blue channels
919 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
920 // set red channel to red + green
921 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
922
923 layer.alpha = 1.0f;
924 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
925
926 layers.push_back(layer);
927
928 invokeDraw(settings, layers);
929}
930
931template <typename SourceVariant>
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800932void RenderEngineTest::fillBufferColorTransform() {
933 fillBufferWithColorTransform<SourceVariant>();
KaiChieh Chuang436fc192020-09-07 13:48:42 +0800934 expectBufferColor(fullscreenRect(), 172, 0, 0, 255, 1);
935}
936
937template <typename SourceVariant>
Sally Qi2019fd22021-11-22 10:19:04 -0800938void RenderEngineTest::fillBufferColorTransformAndSourceDataspace() {
939 unordered_map<ui::Dataspace, ubyte4> dataspaceToColorMap;
Alec Mouric16974e2022-09-13 17:35:48 +0000940 dataspaceToColorMap[ui::Dataspace::V0_BT709] = {77, 0, 0, 255};
941 dataspaceToColorMap[ui::Dataspace::BT2020] = {101, 0, 0, 255};
942 dataspaceToColorMap[ui::Dataspace::ADOBE_RGB] = {75, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -0800943 ui::Dataspace customizedDataspace = static_cast<ui::Dataspace>(
944 ui::Dataspace::STANDARD_BT709 | ui::Dataspace::TRANSFER_GAMMA2_2 |
945 ui::Dataspace::RANGE_FULL);
Alec Mouric16974e2022-09-13 17:35:48 +0000946 dataspaceToColorMap[customizedDataspace] = {61, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -0800947 for (const auto& [sourceDataspace, color] : dataspaceToColorMap) {
948 fillBufferWithColorTransformAndSourceDataspace<SourceVariant>(sourceDataspace);
949 expectBufferColor(fullscreenRect(), color.r, color.g, color.b, color.a, 1);
950 }
951}
952
953template <typename SourceVariant>
954void RenderEngineTest::fillBufferWithColorTransformAndOutputDataspace(
955 const ui::Dataspace outputDataspace) {
956 renderengine::DisplaySettings settings;
957 settings.physicalDisplay = fullscreenRect();
958 settings.clip = Rect(1, 1);
959 settings.outputDataspace = outputDataspace;
960
961 std::vector<renderengine::LayerSettings> layers;
962
963 renderengine::LayerSettings layer;
964 layer.sourceDataspace = ui::Dataspace::V0_SCRGB_LINEAR;
965 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
966 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
967 layer.alpha = 1.0f;
968
969 // construct a fake color matrix
970 // annihilate green and blue channels
971 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
972 // set red channel to red + green
973 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
974
975 layer.alpha = 1.0f;
976 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
977
978 layers.push_back(layer);
979
980 invokeDraw(settings, layers);
981}
982
983template <typename SourceVariant>
984void RenderEngineTest::fillBufferColorTransformAndOutputDataspace() {
985 unordered_map<ui::Dataspace, ubyte4> dataspaceToColorMap;
Alec Mouric16974e2022-09-13 17:35:48 +0000986 dataspaceToColorMap[ui::Dataspace::V0_BT709] = {198, 0, 0, 255};
987 dataspaceToColorMap[ui::Dataspace::BT2020] = {187, 0, 0, 255};
988 dataspaceToColorMap[ui::Dataspace::ADOBE_RGB] = {192, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -0800989 ui::Dataspace customizedDataspace = static_cast<ui::Dataspace>(
990 ui::Dataspace::STANDARD_BT709 | ui::Dataspace::TRANSFER_GAMMA2_6 |
991 ui::Dataspace::RANGE_FULL);
Alec Mouric16974e2022-09-13 17:35:48 +0000992 dataspaceToColorMap[customizedDataspace] = {205, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -0800993 for (const auto& [outputDataspace, color] : dataspaceToColorMap) {
994 fillBufferWithColorTransformAndOutputDataspace<SourceVariant>(outputDataspace);
995 expectBufferColor(fullscreenRect(), color.r, color.g, color.b, color.a, 1);
996 }
997}
998
999template <typename SourceVariant>
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001000void RenderEngineTest::fillBufferWithColorTransformZeroLayerAlpha() {
1001 renderengine::DisplaySettings settings;
1002 settings.physicalDisplay = fullscreenRect();
1003 settings.clip = Rect(1, 1);
1004
Sally Qi59a9f502021-10-12 18:53:23 +00001005 std::vector<renderengine::LayerSettings> layers;
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001006
1007 renderengine::LayerSettings layer;
1008 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1009 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
1010 layer.alpha = 0;
1011
1012 // construct a fake color matrix
1013 // simple inverse color
1014 settings.colorTransform = mat4(-1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 1, 1, 1, 1);
1015
1016 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1017
Sally Qi59a9f502021-10-12 18:53:23 +00001018 layers.push_back(layer);
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001019
Alec Mouric0aae732021-01-12 13:32:18 -08001020 invokeDraw(settings, layers);
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001021}
1022
1023template <typename SourceVariant>
1024void RenderEngineTest::fillBufferColorTransformZeroLayerAlpha() {
1025 fillBufferWithColorTransformZeroLayerAlpha<SourceVariant>();
1026 expectBufferColor(fullscreenRect(), 0, 0, 0, 0);
1027}
1028
1029template <typename SourceVariant>
Alec Mouri7c94edb2018-12-03 21:23:26 -08001030void RenderEngineTest::fillRedBufferWithRoundedCorners() {
1031 renderengine::DisplaySettings settings;
1032 settings.physicalDisplay = fullscreenRect();
1033 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001034 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri7c94edb2018-12-03 21:23:26 -08001035
Sally Qi59a9f502021-10-12 18:53:23 +00001036 std::vector<renderengine::LayerSettings> layers;
Alec Mouri7c94edb2018-12-03 21:23:26 -08001037
1038 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001039 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri7c94edb2018-12-03 21:23:26 -08001040 layer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07001041 layer.geometry.roundedCornersRadius = {5.0f, 5.0f};
Alec Mouri7c94edb2018-12-03 21:23:26 -08001042 layer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
1043 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
1044 layer.alpha = 1.0f;
1045
Sally Qi59a9f502021-10-12 18:53:23 +00001046 layers.push_back(layer);
Alec Mouri7c94edb2018-12-03 21:23:26 -08001047
Alec Mouric0aae732021-01-12 13:32:18 -08001048 invokeDraw(settings, layers);
Alec Mouri7c94edb2018-12-03 21:23:26 -08001049}
1050
1051template <typename SourceVariant>
1052void RenderEngineTest::fillBufferWithRoundedCorners() {
1053 fillRedBufferWithRoundedCorners<SourceVariant>();
1054 // Corners should be ignored...
1055 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 0);
1056 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, 0, DEFAULT_DISPLAY_WIDTH, 1), 0, 0, 0, 0);
1057 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT - 1, 1, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
1058 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1,
1059 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1060 0, 0, 0, 0);
1061 // ...And the non-rounded portion should be red.
1062 // Other pixels may be anti-aliased, so let's not check those.
1063 expectBufferColor(Rect(5, 5, DEFAULT_DISPLAY_WIDTH - 5, DEFAULT_DISPLAY_HEIGHT - 5), 255, 0, 0,
1064 255);
1065}
1066
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001067template <typename SourceVariant>
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001068void RenderEngineTest::fillBufferAndBlurBackground() {
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001069 auto blurRadius = 50;
1070 auto center = DEFAULT_DISPLAY_WIDTH / 2;
1071
1072 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001073 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001074 settings.physicalDisplay = fullscreenRect();
1075 settings.clip = fullscreenRect();
1076
Sally Qi59a9f502021-10-12 18:53:23 +00001077 std::vector<renderengine::LayerSettings> layers;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001078
1079 renderengine::LayerSettings backgroundLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001080 backgroundLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001081 backgroundLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1082 SourceVariant::fillColor(backgroundLayer, 0.0f, 1.0f, 0.0f, this);
1083 backgroundLayer.alpha = 1.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001084 layers.emplace_back(backgroundLayer);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001085
1086 renderengine::LayerSettings leftLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001087 leftLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001088 leftLayer.geometry.boundaries =
1089 Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT).toFloatRect();
1090 SourceVariant::fillColor(leftLayer, 1.0f, 0.0f, 0.0f, this);
1091 leftLayer.alpha = 1.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001092 layers.emplace_back(leftLayer);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001093
1094 renderengine::LayerSettings blurLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001095 blurLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001096 blurLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1097 blurLayer.backgroundBlurRadius = blurRadius;
Derek Sollenbergerecb21462021-01-29 16:53:49 -05001098 SourceVariant::fillColor(blurLayer, 0.0f, 0.0f, 1.0f, this);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001099 blurLayer.alpha = 0;
Sally Qi59a9f502021-10-12 18:53:23 +00001100 layers.emplace_back(blurLayer);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001101
Alec Mouric0aae732021-01-12 13:32:18 -08001102 invokeDraw(settings, layers);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001103
Derek Sollenbergerecb21462021-01-29 16:53:49 -05001104 // solid color
1105 expectBufferColor(Rect(0, 0, 1, 1), 255, 0, 0, 255, 0 /* tolerance */);
1106
Derek Sollenbergerb3998372021-02-16 15:16:56 -05001107 if (mRE->supportsBackgroundBlur()) {
1108 // blurred color (downsampling should result in the center color being close to 128)
1109 expectBufferColor(Rect(center - 1, center - 5, center + 1, center + 5), 128, 128, 0, 255,
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001110 50 /* tolerance */);
Derek Sollenbergerb3998372021-02-16 15:16:56 -05001111 }
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001112}
1113
1114template <typename SourceVariant>
Alec Mourie8489fd2021-04-29 16:08:56 -07001115void RenderEngineTest::fillSmallLayerAndBlurBackground() {
1116 auto blurRadius = 50;
1117 renderengine::DisplaySettings settings;
1118 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1119 settings.physicalDisplay = fullscreenRect();
1120 settings.clip = fullscreenRect();
1121
Sally Qi59a9f502021-10-12 18:53:23 +00001122 std::vector<renderengine::LayerSettings> layers;
Alec Mourie8489fd2021-04-29 16:08:56 -07001123
1124 renderengine::LayerSettings backgroundLayer;
1125 backgroundLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1126 backgroundLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1127 SourceVariant::fillColor(backgroundLayer, 1.0f, 0.0f, 0.0f, this);
1128 backgroundLayer.alpha = 1.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001129 layers.push_back(backgroundLayer);
Alec Mourie8489fd2021-04-29 16:08:56 -07001130
1131 renderengine::LayerSettings blurLayer;
1132 blurLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1133 blurLayer.geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f);
1134 blurLayer.backgroundBlurRadius = blurRadius;
1135 SourceVariant::fillColor(blurLayer, 0.0f, 0.0f, 1.0f, this);
1136 blurLayer.alpha = 0;
Sally Qi59a9f502021-10-12 18:53:23 +00001137 layers.push_back(blurLayer);
Alec Mourie8489fd2021-04-29 16:08:56 -07001138
1139 invokeDraw(settings, layers);
1140
1141 // Give a generous tolerance - the blur rectangle is very small and this test is
1142 // mainly concerned with ensuring that there's no device failure.
1143 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT), 255, 0, 0, 255,
1144 40 /* tolerance */);
1145}
1146
1147template <typename SourceVariant>
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001148void RenderEngineTest::overlayCorners() {
1149 renderengine::DisplaySettings settings;
1150 settings.physicalDisplay = fullscreenRect();
1151 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001152 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001153
Sally Qi59a9f502021-10-12 18:53:23 +00001154 std::vector<renderengine::LayerSettings> layersFirst;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001155
1156 renderengine::LayerSettings layerOne;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001157 layerOne.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001158 layerOne.geometry.boundaries =
1159 FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH / 3.0, DEFAULT_DISPLAY_HEIGHT / 3.0);
1160 SourceVariant::fillColor(layerOne, 1.0f, 0.0f, 0.0f, this);
1161 layerOne.alpha = 0.2;
1162
Sally Qi59a9f502021-10-12 18:53:23 +00001163 layersFirst.push_back(layerOne);
Alec Mouric0aae732021-01-12 13:32:18 -08001164 invokeDraw(settings, layersFirst);
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001165 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3), 51, 0, 0, 51);
1166 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3 + 1, DEFAULT_DISPLAY_HEIGHT / 3 + 1,
1167 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1168 0, 0, 0, 0);
1169
Sally Qi59a9f502021-10-12 18:53:23 +00001170 std::vector<renderengine::LayerSettings> layersSecond;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001171 renderengine::LayerSettings layerTwo;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001172 layerTwo.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001173 layerTwo.geometry.boundaries =
1174 FloatRect(DEFAULT_DISPLAY_WIDTH / 3.0, DEFAULT_DISPLAY_HEIGHT / 3.0,
1175 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT);
1176 SourceVariant::fillColor(layerTwo, 0.0f, 1.0f, 0.0f, this);
1177 layerTwo.alpha = 1.0f;
1178
Sally Qi59a9f502021-10-12 18:53:23 +00001179 layersSecond.push_back(layerTwo);
Alec Mouric0aae732021-01-12 13:32:18 -08001180 invokeDraw(settings, layersSecond);
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001181
1182 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3), 0, 0, 0, 0);
1183 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3 + 1, DEFAULT_DISPLAY_HEIGHT / 3 + 1,
1184 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1185 0, 255, 0, 255);
1186}
1187
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001188void RenderEngineTest::fillRedBufferTextureTransform() {
1189 renderengine::DisplaySettings settings;
1190 settings.physicalDisplay = fullscreenRect();
1191 settings.clip = Rect(1, 1);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001192 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001193
Sally Qi59a9f502021-10-12 18:53:23 +00001194 std::vector<renderengine::LayerSettings> layers;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001195
1196 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001197 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001198 // Here will allocate a checker board texture, but transform texture
1199 // coordinates so that only the upper left is applied.
Alec Mouria90a5702021-04-16 16:36:21 +00001200 const auto buf = allocateSourceBuffer(2, 2);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001201
1202 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00001203 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1204 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001205 // Red top left, Green top right, Blue bottom left, Black bottom right
1206 pixels[0] = 255;
1207 pixels[1] = 0;
1208 pixels[2] = 0;
1209 pixels[3] = 255;
1210 pixels[4] = 0;
1211 pixels[5] = 255;
1212 pixels[6] = 0;
1213 pixels[7] = 255;
1214 pixels[8] = 0;
1215 pixels[9] = 0;
1216 pixels[10] = 255;
1217 pixels[11] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00001218 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001219
1220 layer.source.buffer.buffer = buf;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001221 // Transform coordinates to only be inside the red quadrant.
Alec Mouri4049b532021-10-15 20:59:33 -07001222 layer.source.buffer.textureTransform = mat4::scale(vec4(0.2f, 0.2f, 1.f, 1.f));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001223 layer.alpha = 1.0f;
1224 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1225
Sally Qi59a9f502021-10-12 18:53:23 +00001226 layers.push_back(layer);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001227
Alec Mouric0aae732021-01-12 13:32:18 -08001228 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001229}
1230
1231void RenderEngineTest::fillBufferTextureTransform() {
1232 fillRedBufferTextureTransform();
1233 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
1234}
1235
1236void RenderEngineTest::fillRedBufferWithPremultiplyAlpha() {
1237 renderengine::DisplaySettings settings;
1238 settings.physicalDisplay = fullscreenRect();
1239 // Here logical space is 1x1
1240 settings.clip = Rect(1, 1);
1241
Sally Qi59a9f502021-10-12 18:53:23 +00001242 std::vector<renderengine::LayerSettings> layers;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001243
1244 renderengine::LayerSettings layer;
Alec Mouria90a5702021-04-16 16:36:21 +00001245 const auto buf = allocateSourceBuffer(1, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001246
1247 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00001248 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1249 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001250 pixels[0] = 255;
1251 pixels[1] = 0;
1252 pixels[2] = 0;
1253 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00001254 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001255
1256 layer.source.buffer.buffer = buf;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001257 layer.source.buffer.usePremultipliedAlpha = true;
1258 layer.alpha = 0.5f;
1259 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1260
Sally Qi59a9f502021-10-12 18:53:23 +00001261 layers.push_back(layer);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001262
Alec Mouric0aae732021-01-12 13:32:18 -08001263 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001264}
1265
1266void RenderEngineTest::fillBufferWithPremultiplyAlpha() {
1267 fillRedBufferWithPremultiplyAlpha();
Nolan Scobie01b93b12024-04-03 21:27:34 +00001268 // Different backends and GPUs may round 255 * 0.5 = 127.5 differently, but
1269 // either 127 or 128 are acceptable. Checking both 127 and 128 with a
1270 // tolerance of 1 allows either 127 or 128 to pass, while preventing 126 or
1271 // 129 from erroneously passing.
1272 expectBufferColor(fullscreenRect(), 127, 0, 0, 127, 1);
1273 expectBufferColor(fullscreenRect(), 128, 0, 0, 128, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001274}
1275
1276void RenderEngineTest::fillRedBufferWithoutPremultiplyAlpha() {
1277 renderengine::DisplaySettings settings;
1278 settings.physicalDisplay = fullscreenRect();
1279 // Here logical space is 1x1
1280 settings.clip = Rect(1, 1);
1281
Sally Qi59a9f502021-10-12 18:53:23 +00001282 std::vector<renderengine::LayerSettings> layers;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001283
1284 renderengine::LayerSettings layer;
Alec Mouria90a5702021-04-16 16:36:21 +00001285 const auto buf = allocateSourceBuffer(1, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001286
1287 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00001288 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1289 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001290 pixels[0] = 255;
1291 pixels[1] = 0;
1292 pixels[2] = 0;
1293 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00001294 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001295
1296 layer.source.buffer.buffer = buf;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001297 layer.source.buffer.usePremultipliedAlpha = false;
1298 layer.alpha = 0.5f;
1299 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1300
Sally Qi59a9f502021-10-12 18:53:23 +00001301 layers.push_back(layer);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001302
Alec Mouric0aae732021-01-12 13:32:18 -08001303 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001304}
1305
1306void RenderEngineTest::fillBufferWithoutPremultiplyAlpha() {
1307 fillRedBufferWithoutPremultiplyAlpha();
wukui16f3c0bb2020-08-05 20:35:29 +08001308 expectBufferColor(fullscreenRect(), 128, 0, 0, 128, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001309}
1310
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001311template <typename SourceVariant>
1312void RenderEngineTest::drawShadow(const renderengine::LayerSettings& castingLayer,
Vishnu Naird9e4f462023-10-06 04:05:45 +00001313 const ShadowSettings& shadow, const ubyte4& casterColor,
1314 const ubyte4& backgroundColor) {
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001315 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001316 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001317 settings.physicalDisplay = fullscreenRect();
1318 settings.clip = fullscreenRect();
1319
Sally Qi59a9f502021-10-12 18:53:23 +00001320 std::vector<renderengine::LayerSettings> layers;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001321
1322 // add background layer
1323 renderengine::LayerSettings bgLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001324 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001325 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1326 ColorSourceVariant::fillColor(bgLayer, backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1327 backgroundColor.b / 255.0f, this);
1328 bgLayer.alpha = backgroundColor.a / 255.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001329 layers.push_back(bgLayer);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001330
1331 // add shadow layer
1332 renderengine::LayerSettings shadowLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001333 shadowLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001334 shadowLayer.geometry.boundaries = castingLayer.geometry.boundaries;
1335 shadowLayer.alpha = castingLayer.alpha;
1336 shadowLayer.shadow = shadow;
Sally Qi59a9f502021-10-12 18:53:23 +00001337 layers.push_back(shadowLayer);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001338
1339 // add layer casting the shadow
1340 renderengine::LayerSettings layer = castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001341 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001342 SourceVariant::fillColor(layer, casterColor.r / 255.0f, casterColor.g / 255.0f,
1343 casterColor.b / 255.0f, this);
Sally Qi59a9f502021-10-12 18:53:23 +00001344 layers.push_back(layer);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001345
Alec Mouric0aae732021-01-12 13:32:18 -08001346 invokeDraw(settings, layers);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001347}
1348
Alec Mouribd17b3b2020-12-17 11:08:30 -08001349void RenderEngineTest::drawShadowWithoutCaster(const FloatRect& castingBounds,
Vishnu Naird9e4f462023-10-06 04:05:45 +00001350 const ShadowSettings& shadow,
Alec Mouribd17b3b2020-12-17 11:08:30 -08001351 const ubyte4& backgroundColor) {
1352 renderengine::DisplaySettings settings;
1353 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1354 settings.physicalDisplay = fullscreenRect();
1355 settings.clip = fullscreenRect();
1356
Sally Qi59a9f502021-10-12 18:53:23 +00001357 std::vector<renderengine::LayerSettings> layers;
Alec Mouribd17b3b2020-12-17 11:08:30 -08001358
1359 // add background layer
1360 renderengine::LayerSettings bgLayer;
1361 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1362 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1363 ColorSourceVariant::fillColor(bgLayer, backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1364 backgroundColor.b / 255.0f, this);
1365 bgLayer.alpha = backgroundColor.a / 255.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001366 layers.push_back(bgLayer);
Alec Mouribd17b3b2020-12-17 11:08:30 -08001367
1368 // add shadow layer
1369 renderengine::LayerSettings shadowLayer;
1370 shadowLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1371 shadowLayer.geometry.boundaries = castingBounds;
Derek Sollenbergerc31985e2021-05-18 16:38:17 -04001372 shadowLayer.skipContentDraw = true;
Alec Mouribd17b3b2020-12-17 11:08:30 -08001373 shadowLayer.alpha = 1.0f;
1374 ColorSourceVariant::fillColor(shadowLayer, 0, 0, 0, this);
1375 shadowLayer.shadow = shadow;
Sally Qi59a9f502021-10-12 18:53:23 +00001376 layers.push_back(shadowLayer);
Alec Mouribd17b3b2020-12-17 11:08:30 -08001377
Alec Mouric0aae732021-01-12 13:32:18 -08001378 invokeDraw(settings, layers);
Alec Mouribd17b3b2020-12-17 11:08:30 -08001379}
1380
Alec Mouri5a493722022-01-26 16:43:02 -08001381void RenderEngineTest::tonemap(ui::Dataspace sourceDataspace, std::function<vec3(vec3)> eotf,
1382 std::function<vec3(vec3, float)> scaleOotf) {
1383 constexpr int32_t kGreyLevels = 256;
1384
1385 const auto rect = Rect(0, 0, kGreyLevels, 1);
1386
1387 constexpr float kMaxLuminance = 750.f;
1388 constexpr float kCurrentLuminanceNits = 500.f;
1389 const renderengine::DisplaySettings display{
1390 .physicalDisplay = rect,
1391 .clip = rect,
1392 .maxLuminance = kMaxLuminance,
1393 .currentLuminanceNits = kCurrentLuminanceNits,
1394 .outputDataspace = ui::Dataspace::DISPLAY_P3,
1395 };
1396
1397 auto buf = std::make_shared<
1398 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07001399 ExternalTexture>(sp<GraphicBuffer>::make(kGreyLevels, 1,
1400 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1401 GRALLOC_USAGE_SW_READ_OFTEN |
1402 GRALLOC_USAGE_SW_WRITE_OFTEN |
1403 GRALLOC_USAGE_HW_RENDER |
1404 GRALLOC_USAGE_HW_TEXTURE,
1405 "input"),
Alec Mouri5a493722022-01-26 16:43:02 -08001406 *mRE,
1407 renderengine::impl::ExternalTexture::Usage::READABLE |
1408 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
1409 ASSERT_EQ(0, buf->getBuffer()->initCheck());
1410 {
1411 uint8_t* pixels;
1412 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1413 reinterpret_cast<void**>(&pixels));
1414
1415 uint8_t color = 0;
1416 for (int32_t j = 0; j < buf->getBuffer()->getHeight(); j++) {
1417 uint8_t* dest = pixels + (buf->getBuffer()->getStride() * j * 4);
1418 for (int32_t i = 0; i < buf->getBuffer()->getWidth(); i++) {
1419 dest[0] = color;
1420 dest[1] = color;
1421 dest[2] = color;
1422 dest[3] = 255;
1423 color++;
1424 dest += 4;
1425 }
1426 }
1427 buf->getBuffer()->unlock();
1428 }
1429
1430 mBuffer = std::make_shared<
1431 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07001432 ExternalTexture>(sp<GraphicBuffer>::make(kGreyLevels, 1,
1433 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1434 GRALLOC_USAGE_SW_READ_OFTEN |
1435 GRALLOC_USAGE_SW_WRITE_OFTEN |
1436 GRALLOC_USAGE_HW_RENDER |
1437 GRALLOC_USAGE_HW_TEXTURE,
1438 "output"),
Alec Mouri5a493722022-01-26 16:43:02 -08001439 *mRE,
1440 renderengine::impl::ExternalTexture::Usage::READABLE |
1441 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
1442 ASSERT_EQ(0, mBuffer->getBuffer()->initCheck());
1443
1444 const renderengine::LayerSettings layer{.geometry.boundaries = rect.toFloatRect(),
1445 .source =
1446 renderengine::PixelSource{
1447 .buffer =
1448 renderengine::Buffer{
1449 .buffer =
1450 std::move(buf),
1451 .usePremultipliedAlpha =
1452 true,
1453 },
1454 },
1455 .alpha = 1.0f,
1456 .sourceDataspace = sourceDataspace};
1457
1458 std::vector<renderengine::LayerSettings> layers{layer};
1459 invokeDraw(display, layers);
1460
1461 ColorSpace displayP3 = ColorSpace::DisplayP3();
1462 ColorSpace bt2020 = ColorSpace::BT2020();
1463
1464 tonemap::Metadata metadata{.displayMaxLuminance = 750.0f};
1465
1466 auto generator = [=](Point location) {
1467 const double normColor = static_cast<double>(location.x) / (kGreyLevels - 1);
1468 const vec3 rgb = vec3(normColor, normColor, normColor);
1469
1470 const vec3 linearRGB = eotf(rgb);
1471
1472 const vec3 xyz = bt2020.getRGBtoXYZ() * linearRGB;
1473
1474 const vec3 scaledXYZ = scaleOotf(xyz, kCurrentLuminanceNits);
Alec Mouri196b0f22022-03-04 22:13:48 +00001475 const auto gains =
Alec Mouri5a493722022-01-26 16:43:02 -08001476 tonemap::getToneMapper()
1477 ->lookupTonemapGain(static_cast<aidl::android::hardware::graphics::common::
1478 Dataspace>(sourceDataspace),
1479 static_cast<aidl::android::hardware::graphics::common::
1480 Dataspace>(
1481 ui::Dataspace::DISPLAY_P3),
Alec Mouri196b0f22022-03-04 22:13:48 +00001482 {tonemap::
1483 Color{.linearRGB =
1484 scaleOotf(linearRGB,
1485 kCurrentLuminanceNits),
1486 .xyz = scaledXYZ}},
Alec Mouri5a493722022-01-26 16:43:02 -08001487 metadata);
Alec Mouri196b0f22022-03-04 22:13:48 +00001488 EXPECT_EQ(1, gains.size());
1489 const double gain = gains.front();
Alec Mouri5a493722022-01-26 16:43:02 -08001490 const vec3 normalizedXYZ = scaledXYZ * gain / metadata.displayMaxLuminance;
1491
1492 const vec3 targetRGB = OETF_sRGB(displayP3.getXYZtoRGB() * normalizedXYZ) * 255;
1493 return ubyte4(static_cast<uint8_t>(targetRGB.r), static_cast<uint8_t>(targetRGB.g),
1494 static_cast<uint8_t>(targetRGB.b), 255);
1495 };
1496
1497 expectBufferColor(Rect(kGreyLevels, 1), generator, 2);
1498}
1499
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001500INSTANTIATE_TEST_SUITE_P(PerRenderEngineType, RenderEngineTest,
Alec Mouric16974e2022-09-13 17:35:48 +00001501 testing::Values(std::make_shared<SkiaGLESRenderEngineFactory>(),
Nolan Scobie195631a2024-03-26 12:22:23 -04001502 std::make_shared<GaneshVkRenderEngineFactory>(),
1503 std::make_shared<GraphiteVkRenderEngineFactory>()));
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001504
1505TEST_P(RenderEngineTest, drawLayers_noLayersToDraw) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001506 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001507 GTEST_SKIP();
1508 }
Alec Mouric0aae732021-01-12 13:32:18 -08001509 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001510 drawEmptyLayers();
1511}
1512
Sally Qi1fed86e2022-06-23 15:33:52 -07001513TEST_P(RenderEngineTest, drawLayers_fillRedBufferAndEmptyBuffer) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001514 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001515 GTEST_SKIP();
1516 }
Sally Qi1fed86e2022-06-23 15:33:52 -07001517 initializeRenderEngine();
1518 renderengine::DisplaySettings settings;
1519 settings.physicalDisplay = fullscreenRect();
1520 settings.clip = fullscreenRect();
1521 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1522
1523 // add a red layer
1524 renderengine::LayerSettings layerOne{
1525 .geometry.boundaries = fullscreenRect().toFloatRect(),
1526 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
1527 .alpha = 1.f,
1528 };
1529
1530 std::vector<renderengine::LayerSettings> layersFirst{layerOne};
1531 invokeDraw(settings, layersFirst);
1532 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
1533
1534 // re-draw with an empty layer above it, and we get a transparent black one
1535 std::vector<renderengine::LayerSettings> layersSecond;
1536 invokeDraw(settings, layersSecond);
1537 expectBufferColor(fullscreenRect(), 0, 0, 0, 0);
1538}
1539
Ana Krulec07b98df2021-01-07 14:38:40 -08001540TEST_P(RenderEngineTest, drawLayers_withoutBuffers_withColorTransform) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001541 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001542 GTEST_SKIP();
1543 }
Alec Mouria90a5702021-04-16 16:36:21 +00001544 initializeRenderEngine();
Ana Krulec07b98df2021-01-07 14:38:40 -08001545
1546 renderengine::DisplaySettings settings;
1547 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1548 settings.physicalDisplay = fullscreenRect();
1549 settings.clip = fullscreenRect();
1550
1551 // 255, 255, 255, 255 is full opaque white.
Alec Mouri4049b532021-10-15 20:59:33 -07001552 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
1553 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Ana Krulec07b98df2021-01-07 14:38:40 -08001554 // Create layer with given color.
1555 renderengine::LayerSettings bgLayer;
1556 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1557 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1558 bgLayer.source.solidColor = half3(backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1559 backgroundColor.b / 255.0f);
1560 bgLayer.alpha = backgroundColor.a / 255.0f;
1561 // Transform the red color.
1562 bgLayer.colorTransform = mat4(-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
1563
Sally Qi59a9f502021-10-12 18:53:23 +00001564 std::vector<renderengine::LayerSettings> layers;
1565 layers.push_back(bgLayer);
Ana Krulec07b98df2021-01-07 14:38:40 -08001566
Alec Mouric0aae732021-01-12 13:32:18 -08001567 invokeDraw(settings, layers);
Ana Krulec07b98df2021-01-07 14:38:40 -08001568
1569 // Expect to see full opaque pixel (with inverted red from the transform).
Alec Mouric0aae732021-01-12 13:32:18 -08001570 expectBufferColor(Rect(0, 0, 10, 10), 0.f, backgroundColor.g, backgroundColor.b,
Ana Krulec07b98df2021-01-07 14:38:40 -08001571 backgroundColor.a);
1572}
1573
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001574TEST_P(RenderEngineTest, drawLayers_nullOutputBuffer) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001575 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001576 GTEST_SKIP();
1577 }
Alec Mouric0aae732021-01-12 13:32:18 -08001578 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001579
Alec Mourid43ccab2019-03-13 12:23:45 -07001580 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001581 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Sally Qi59a9f502021-10-12 18:53:23 +00001582 std::vector<renderengine::LayerSettings> layers;
Alec Mourid43ccab2019-03-13 12:23:45 -07001583 renderengine::LayerSettings layer;
1584 layer.geometry.boundaries = fullscreenRect().toFloatRect();
1585 BufferSourceVariant<ForceOpaqueBufferVariant>::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
Sally Qi59a9f502021-10-12 18:53:23 +00001586 layers.push_back(layer);
Alec Mourif29700f2023-08-17 21:53:31 +00001587 ftl::Future<FenceResult> future = mRE->drawLayers(settings, layers, nullptr, base::unique_fd());
Alec Mourid43ccab2019-03-13 12:23:45 -07001588
Patrick Williams2e9748f2022-08-09 22:48:18 +00001589 ASSERT_TRUE(future.valid());
1590 auto result = future.get();
1591 ASSERT_FALSE(result.ok());
1592 ASSERT_EQ(BAD_VALUE, result.error());
Alec Mourid43ccab2019-03-13 12:23:45 -07001593}
1594
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001595TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001596 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001597 GTEST_SKIP();
1598 }
Alec Mouric0aae732021-01-12 13:32:18 -08001599 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001600 fillRedBuffer<ColorSourceVariant>();
1601}
1602
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001603TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001604 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001605 GTEST_SKIP();
1606 }
Alec Mouric0aae732021-01-12 13:32:18 -08001607 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001608 fillGreenBuffer<ColorSourceVariant>();
1609}
1610
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001611TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001612 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001613 GTEST_SKIP();
1614 }
Alec Mouric0aae732021-01-12 13:32:18 -08001615 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001616 fillBlueBuffer<ColorSourceVariant>();
1617}
1618
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001619TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001620 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001621 GTEST_SKIP();
1622 }
Alec Mouric0aae732021-01-12 13:32:18 -08001623 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001624 fillRedTransparentBuffer<ColorSourceVariant>();
1625}
1626
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001627TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001628 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001629 GTEST_SKIP();
1630 }
Alec Mouric0aae732021-01-12 13:32:18 -08001631 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001632 fillBufferPhysicalOffset<ColorSourceVariant>();
1633}
1634
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001635TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001636 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001637 GTEST_SKIP();
1638 }
Alec Mouric0aae732021-01-12 13:32:18 -08001639 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001640 fillBufferCheckersRotate0<ColorSourceVariant>();
1641}
1642
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001643TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001644 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001645 GTEST_SKIP();
1646 }
Alec Mouric0aae732021-01-12 13:32:18 -08001647 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001648 fillBufferCheckersRotate90<ColorSourceVariant>();
1649}
1650
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001651TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001652 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001653 GTEST_SKIP();
1654 }
Alec Mouric0aae732021-01-12 13:32:18 -08001655 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001656 fillBufferCheckersRotate180<ColorSourceVariant>();
1657}
1658
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001659TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001660 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001661 GTEST_SKIP();
1662 }
Alec Mouric0aae732021-01-12 13:32:18 -08001663 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001664 fillBufferCheckersRotate270<ColorSourceVariant>();
1665}
1666
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001667TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001668 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001669 GTEST_SKIP();
1670 }
Alec Mouric0aae732021-01-12 13:32:18 -08001671 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001672 fillBufferLayerTransform<ColorSourceVariant>();
1673}
1674
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001675TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001676 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001677 GTEST_SKIP();
1678 }
Alec Mouric0aae732021-01-12 13:32:18 -08001679 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08001680 fillBufferColorTransform<ColorSourceVariant>();
1681}
1682
Sally Qi2019fd22021-11-22 10:19:04 -08001683TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_sourceDataspace) {
1684 const auto& renderEngineFactory = GetParam();
1685 // skip for non color management
Leon Scroggins III696bf932024-01-24 15:21:05 -05001686 if (!renderEngineFactory->apiSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001687 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001688 }
1689
1690 initializeRenderEngine();
1691 fillBufferColorTransformAndSourceDataspace<ColorSourceVariant>();
1692}
1693
1694TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_outputDataspace) {
Nolan Scobie195631a2024-03-26 12:22:23 -04001695 // TODO: b/331445583 - Fix in Graphite and re-enable.
1696 if (GetParam()->skiaBackend() == renderengine::RenderEngine::SkiaBackend::GRAPHITE) {
1697 GTEST_SKIP();
1698 }
1699
Sally Qi2019fd22021-11-22 10:19:04 -08001700 const auto& renderEngineFactory = GetParam();
1701 // skip for non color management
Leon Scroggins III696bf932024-01-24 15:21:05 -05001702 if (!renderEngineFactory->apiSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001703 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001704 }
1705
1706 initializeRenderEngine();
1707 fillBufferColorTransformAndOutputDataspace<ColorSourceVariant>();
1708}
1709
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001710TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001711 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001712 GTEST_SKIP();
1713 }
Alec Mouric0aae732021-01-12 13:32:18 -08001714 initializeRenderEngine();
Alec Mouri7c94edb2018-12-03 21:23:26 -08001715 fillBufferWithRoundedCorners<ColorSourceVariant>();
1716}
1717
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001718TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001719 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001720 GTEST_SKIP();
1721 }
Alec Mouric0aae732021-01-12 13:32:18 -08001722 initializeRenderEngine();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001723 fillBufferColorTransformZeroLayerAlpha<ColorSourceVariant>();
1724}
1725
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001726TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001727 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001728 GTEST_SKIP();
1729 }
Alec Mouric0aae732021-01-12 13:32:18 -08001730 initializeRenderEngine();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001731 fillBufferAndBlurBackground<ColorSourceVariant>();
1732}
1733
Alec Mourie8489fd2021-04-29 16:08:56 -07001734TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001735 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001736 GTEST_SKIP();
1737 }
Alec Mourie8489fd2021-04-29 16:08:56 -07001738 initializeRenderEngine();
1739 fillSmallLayerAndBlurBackground<ColorSourceVariant>();
1740}
1741
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001742TEST_P(RenderEngineTest, drawLayers_overlayCorners_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001743 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001744 GTEST_SKIP();
1745 }
Alec Mouric0aae732021-01-12 13:32:18 -08001746 initializeRenderEngine();
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001747 overlayCorners<ColorSourceVariant>();
1748}
1749
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001750TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001751 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001752 GTEST_SKIP();
1753 }
Alec Mouric0aae732021-01-12 13:32:18 -08001754 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001755 fillRedBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1756}
1757
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001758TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001759 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001760 GTEST_SKIP();
1761 }
Alec Mouric0aae732021-01-12 13:32:18 -08001762 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001763 fillGreenBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1764}
1765
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001766TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001767 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001768 GTEST_SKIP();
1769 }
Alec Mouric0aae732021-01-12 13:32:18 -08001770 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001771 fillBlueBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1772}
1773
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001774TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001775 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001776 GTEST_SKIP();
1777 }
Alec Mouric0aae732021-01-12 13:32:18 -08001778 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001779 fillRedTransparentBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1780}
1781
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001782TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001783 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001784 GTEST_SKIP();
1785 }
Alec Mouric0aae732021-01-12 13:32:18 -08001786 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001787 fillBufferPhysicalOffset<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1788}
1789
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001790TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001791 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001792 GTEST_SKIP();
1793 }
Alec Mouric0aae732021-01-12 13:32:18 -08001794 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001795 fillBufferCheckersRotate0<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1796}
1797
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001798TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001799 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001800 GTEST_SKIP();
1801 }
Alec Mouric0aae732021-01-12 13:32:18 -08001802 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001803 fillBufferCheckersRotate90<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1804}
1805
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001806TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001807 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001808 GTEST_SKIP();
1809 }
Alec Mouric0aae732021-01-12 13:32:18 -08001810 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001811 fillBufferCheckersRotate180<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1812}
1813
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001814TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001815 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001816 GTEST_SKIP();
1817 }
Alec Mouric0aae732021-01-12 13:32:18 -08001818 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001819 fillBufferCheckersRotate270<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1820}
1821
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001822TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001823 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001824 GTEST_SKIP();
1825 }
Alec Mouric0aae732021-01-12 13:32:18 -08001826 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001827 fillBufferLayerTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1828}
1829
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001830TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001831 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001832 GTEST_SKIP();
1833 }
Alec Mouric0aae732021-01-12 13:32:18 -08001834 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08001835 fillBufferColorTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1836}
1837
Sally Qi2019fd22021-11-22 10:19:04 -08001838TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndSourceDataspace_opaqueBufferSource) {
1839 const auto& renderEngineFactory = GetParam();
1840 // skip for non color management
Leon Scroggins III696bf932024-01-24 15:21:05 -05001841 if (!renderEngineFactory->apiSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001842 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001843 }
1844
1845 initializeRenderEngine();
1846 fillBufferColorTransformAndSourceDataspace<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1847}
1848
1849TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndOutputDataspace_opaqueBufferSource) {
Nolan Scobie195631a2024-03-26 12:22:23 -04001850 // TODO: b/331447131 - Fix in Graphite and re-enable.
1851 if (GetParam()->skiaBackend() == renderengine::RenderEngine::SkiaBackend::GRAPHITE) {
1852 GTEST_SKIP();
1853 }
1854
Sally Qi2019fd22021-11-22 10:19:04 -08001855 const auto& renderEngineFactory = GetParam();
1856 // skip for non color management
Leon Scroggins III696bf932024-01-24 15:21:05 -05001857 if (!renderEngineFactory->apiSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001858 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001859 }
1860
1861 initializeRenderEngine();
1862 fillBufferColorTransformAndOutputDataspace<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1863}
1864
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001865TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001866 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001867 GTEST_SKIP();
1868 }
Alec Mouric0aae732021-01-12 13:32:18 -08001869 initializeRenderEngine();
Alec Mouri7c94edb2018-12-03 21:23:26 -08001870 fillBufferWithRoundedCorners<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1871}
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001872
Alec Mouric0aae732021-01-12 13:32:18 -08001873TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001874 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001875 GTEST_SKIP();
1876 }
Alec Mouric0aae732021-01-12 13:32:18 -08001877 initializeRenderEngine();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001878 fillBufferColorTransformZeroLayerAlpha<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1879}
Alec Mouri7c94edb2018-12-03 21:23:26 -08001880
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001881TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001882 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001883 GTEST_SKIP();
1884 }
Alec Mouric0aae732021-01-12 13:32:18 -08001885 initializeRenderEngine();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001886 fillBufferAndBlurBackground<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1887}
1888
Alec Mourie8489fd2021-04-29 16:08:56 -07001889TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001890 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001891 GTEST_SKIP();
1892 }
Alec Mourie8489fd2021-04-29 16:08:56 -07001893 initializeRenderEngine();
1894 fillSmallLayerAndBlurBackground<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1895}
1896
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001897TEST_P(RenderEngineTest, drawLayers_overlayCorners_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001898 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001899 GTEST_SKIP();
1900 }
Alec Mouric0aae732021-01-12 13:32:18 -08001901 initializeRenderEngine();
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001902 overlayCorners<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1903}
1904
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001905TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001906 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001907 GTEST_SKIP();
1908 }
Alec Mouric0aae732021-01-12 13:32:18 -08001909 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001910 fillRedBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1911}
1912
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001913TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001914 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001915 GTEST_SKIP();
1916 }
Alec Mouric0aae732021-01-12 13:32:18 -08001917 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001918 fillGreenBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1919}
1920
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001921TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001922 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001923 GTEST_SKIP();
1924 }
Alec Mouric0aae732021-01-12 13:32:18 -08001925 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001926 fillBlueBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1927}
1928
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001929TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001930 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001931 GTEST_SKIP();
1932 }
Alec Mouric0aae732021-01-12 13:32:18 -08001933 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001934 fillRedTransparentBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1935}
1936
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001937TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001938 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001939 GTEST_SKIP();
1940 }
Alec Mouric0aae732021-01-12 13:32:18 -08001941 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001942 fillBufferPhysicalOffset<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1943}
1944
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001945TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001946 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001947 GTEST_SKIP();
1948 }
Alec Mouric0aae732021-01-12 13:32:18 -08001949 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001950 fillBufferCheckersRotate0<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1951}
1952
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001953TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001954 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001955 GTEST_SKIP();
1956 }
Alec Mouric0aae732021-01-12 13:32:18 -08001957 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001958 fillBufferCheckersRotate90<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1959}
1960
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001961TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001962 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001963 GTEST_SKIP();
1964 }
Alec Mouric0aae732021-01-12 13:32:18 -08001965 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001966 fillBufferCheckersRotate180<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1967}
1968
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001969TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001970 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001971 GTEST_SKIP();
1972 }
Alec Mouric0aae732021-01-12 13:32:18 -08001973 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001974 fillBufferCheckersRotate270<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1975}
1976
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001977TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001978 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001979 GTEST_SKIP();
1980 }
Alec Mouric0aae732021-01-12 13:32:18 -08001981 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001982 fillBufferLayerTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1983}
1984
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001985TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001986 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001987 GTEST_SKIP();
1988 }
Alec Mouric0aae732021-01-12 13:32:18 -08001989 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08001990 fillBufferColorTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1991}
1992
Sally Qi2019fd22021-11-22 10:19:04 -08001993TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndSourceDataspace_bufferSource) {
1994 const auto& renderEngineFactory = GetParam();
1995 // skip for non color management
Leon Scroggins III696bf932024-01-24 15:21:05 -05001996 if (!renderEngineFactory->apiSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001997 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001998 }
1999
2000 initializeRenderEngine();
2001 fillBufferColorTransformAndSourceDataspace<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2002}
2003
2004TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndOutputDataspace_bufferSource) {
Nolan Scobie195631a2024-03-26 12:22:23 -04002005 // TODO: b/331446495 - Fix in Graphite and re-enable.
2006 if (GetParam()->skiaBackend() == renderengine::RenderEngine::SkiaBackend::GRAPHITE) {
2007 GTEST_SKIP();
2008 }
2009
Sally Qi2019fd22021-11-22 10:19:04 -08002010 const auto& renderEngineFactory = GetParam();
2011 // skip for non color management
Leon Scroggins III696bf932024-01-24 15:21:05 -05002012 if (!renderEngineFactory->apiSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00002013 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08002014 }
2015
2016 initializeRenderEngine();
2017 fillBufferColorTransformAndOutputDataspace<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2018}
2019
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002020TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002021 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002022 GTEST_SKIP();
2023 }
Alec Mouric0aae732021-01-12 13:32:18 -08002024 initializeRenderEngine();
Alec Mouri7c94edb2018-12-03 21:23:26 -08002025 fillBufferWithRoundedCorners<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2026}
2027
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08002028TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002029 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002030 GTEST_SKIP();
2031 }
Alec Mouric0aae732021-01-12 13:32:18 -08002032 initializeRenderEngine();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08002033 fillBufferColorTransformZeroLayerAlpha<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2034}
2035
Nathaniel Nifong53494f32021-04-30 14:05:39 -04002036TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002037 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002038 GTEST_SKIP();
2039 }
Alec Mouric0aae732021-01-12 13:32:18 -08002040 initializeRenderEngine();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08002041 fillBufferAndBlurBackground<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2042}
2043
Alec Mourie8489fd2021-04-29 16:08:56 -07002044TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002045 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002046 GTEST_SKIP();
2047 }
Alec Mourie8489fd2021-04-29 16:08:56 -07002048 initializeRenderEngine();
2049 fillSmallLayerAndBlurBackground<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2050}
2051
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002052TEST_P(RenderEngineTest, drawLayers_overlayCorners_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002053 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002054 GTEST_SKIP();
2055 }
Alec Mouric0aae732021-01-12 13:32:18 -08002056 initializeRenderEngine();
Alec Mourie7d1d4a2019-02-05 01:13:46 +00002057 overlayCorners<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2058}
2059
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002060TEST_P(RenderEngineTest, drawLayers_fillBufferTextureTransform) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002061 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002062 GTEST_SKIP();
2063 }
Alec Mouric0aae732021-01-12 13:32:18 -08002064 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002065 fillBufferTextureTransform();
2066}
2067
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002068TEST_P(RenderEngineTest, drawLayers_fillBuffer_premultipliesAlpha) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002069 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002070 GTEST_SKIP();
2071 }
Alec Mouric0aae732021-01-12 13:32:18 -08002072 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002073 fillBufferWithPremultiplyAlpha();
2074}
2075
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002076TEST_P(RenderEngineTest, drawLayers_fillBuffer_withoutPremultiplyingAlpha) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002077 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002078 GTEST_SKIP();
2079 }
Alec Mouric0aae732021-01-12 13:32:18 -08002080 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002081 fillBufferWithoutPremultiplyAlpha();
2082}
2083
Alec Mouribd17b3b2020-12-17 11:08:30 -08002084TEST_P(RenderEngineTest, drawLayers_fillShadow_castsWithoutCasterLayer) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002085 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002086 GTEST_SKIP();
2087 }
Alec Mouric0aae732021-01-12 13:32:18 -08002088 initializeRenderEngine();
Alec Mouribd17b3b2020-12-17 11:08:30 -08002089
Alec Mouri4049b532021-10-15 20:59:33 -07002090 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2091 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Alec Mouribd17b3b2020-12-17 11:08:30 -08002092 const float shadowLength = 5.0f;
2093 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2094 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
Vishnu Naird9e4f462023-10-06 04:05:45 +00002095 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2096 shadowLength, false /* casterIsTranslucent */);
Alec Mouribd17b3b2020-12-17 11:08:30 -08002097
2098 drawShadowWithoutCaster(casterBounds.toFloatRect(), settings, backgroundColor);
2099 expectShadowColorWithoutCaster(casterBounds.toFloatRect(), settings, backgroundColor);
2100}
2101
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002102TEST_P(RenderEngineTest, drawLayers_fillShadow_casterLayerMinSize) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002103 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002104 GTEST_SKIP();
2105 }
Alec Mouric0aae732021-01-12 13:32:18 -08002106 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002107
Alec Mouri4049b532021-10-15 20:59:33 -07002108 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2109 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2110 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2111 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002112 const float shadowLength = 5.0f;
2113 Rect casterBounds(1, 1);
2114 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2115 renderengine::LayerSettings castingLayer;
2116 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2117 castingLayer.alpha = 1.0f;
Vishnu Naird9e4f462023-10-06 04:05:45 +00002118 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2119 shadowLength, false /* casterIsTranslucent */);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002120
2121 drawShadow<ColorSourceVariant>(castingLayer, settings, casterColor, backgroundColor);
2122 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2123}
2124
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002125TEST_P(RenderEngineTest, drawLayers_fillShadow_casterColorLayer) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002126 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002127 GTEST_SKIP();
2128 }
Alec Mouric0aae732021-01-12 13:32:18 -08002129 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002130
Alec Mouri4049b532021-10-15 20:59:33 -07002131 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2132 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2133 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2134 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002135 const float shadowLength = 5.0f;
2136 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2137 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2138 renderengine::LayerSettings castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002139 castingLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002140 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2141 castingLayer.alpha = 1.0f;
Vishnu Naird9e4f462023-10-06 04:05:45 +00002142 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2143 shadowLength, false /* casterIsTranslucent */);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002144
2145 drawShadow<ColorSourceVariant>(castingLayer, settings, casterColor, backgroundColor);
2146 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2147}
2148
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002149TEST_P(RenderEngineTest, drawLayers_fillShadow_casterOpaqueBufferLayer) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002150 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002151 GTEST_SKIP();
2152 }
Alec Mouric0aae732021-01-12 13:32:18 -08002153 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002154
Alec Mouri4049b532021-10-15 20:59:33 -07002155 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2156 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2157 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2158 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002159 const float shadowLength = 5.0f;
2160 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2161 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2162 renderengine::LayerSettings castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002163 castingLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002164 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2165 castingLayer.alpha = 1.0f;
Vishnu Naird9e4f462023-10-06 04:05:45 +00002166 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2167 shadowLength, false /* casterIsTranslucent */);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002168
2169 drawShadow<BufferSourceVariant<ForceOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2170 backgroundColor);
2171 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2172}
2173
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002174TEST_P(RenderEngineTest, drawLayers_fillShadow_casterWithRoundedCorner) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002175 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002176 GTEST_SKIP();
2177 }
Alec Mouric0aae732021-01-12 13:32:18 -08002178 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002179
Alec Mouri4049b532021-10-15 20:59:33 -07002180 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2181 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2182 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2183 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002184 const float shadowLength = 5.0f;
2185 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2186 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2187 renderengine::LayerSettings castingLayer;
2188 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002189 castingLayer.geometry.roundedCornersRadius = {3.0f, 3.0f};
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002190 castingLayer.geometry.roundedCornersCrop = casterBounds.toFloatRect();
2191 castingLayer.alpha = 1.0f;
Vishnu Naird9e4f462023-10-06 04:05:45 +00002192 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2193 shadowLength, false /* casterIsTranslucent */);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002194
2195 drawShadow<BufferSourceVariant<ForceOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2196 backgroundColor);
2197 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2198}
2199
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002200TEST_P(RenderEngineTest, drawLayers_fillShadow_translucentCasterWithAlpha) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002201 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002202 GTEST_SKIP();
2203 }
Alec Mouric0aae732021-01-12 13:32:18 -08002204 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002205
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002206 const ubyte4 casterColor(255, 0, 0, 255);
2207 const ubyte4 backgroundColor(255, 255, 255, 255);
2208 const float shadowLength = 5.0f;
2209 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2210 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2211 renderengine::LayerSettings castingLayer;
2212 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2213 castingLayer.alpha = 0.5f;
Vishnu Naird9e4f462023-10-06 04:05:45 +00002214 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2215 shadowLength, true /* casterIsTranslucent */);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002216
2217 drawShadow<BufferSourceVariant<RelaxOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2218 backgroundColor);
2219
2220 // verify only the background since the shadow will draw behind the caster
2221 const float shadowInset = settings.length * -1.0f;
2222 const Rect casterWithShadow =
2223 Rect(casterBounds).inset(shadowInset, shadowInset, shadowInset, shadowInset);
2224 const Region backgroundRegion = Region(fullscreenRect()).subtractSelf(casterWithShadow);
2225 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
2226 backgroundColor.a);
2227}
2228
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002229TEST_P(RenderEngineTest, cleanupPostRender_cleansUpOnce) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002230 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002231 GTEST_SKIP();
2232 }
Alec Mouric0aae732021-01-12 13:32:18 -08002233 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002234
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002235 renderengine::DisplaySettings settings;
2236 settings.physicalDisplay = fullscreenRect();
2237 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002238 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002239
Sally Qi59a9f502021-10-12 18:53:23 +00002240 std::vector<renderengine::LayerSettings> layers;
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002241 renderengine::LayerSettings layer;
2242 layer.geometry.boundaries = fullscreenRect().toFloatRect();
2243 BufferSourceVariant<ForceOpaqueBufferVariant>::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
2244 layer.alpha = 1.0;
Sally Qi59a9f502021-10-12 18:53:23 +00002245 layers.push_back(layer);
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002246
Patrick Williams2e9748f2022-08-09 22:48:18 +00002247 ftl::Future<FenceResult> futureOne =
Alec Mourif29700f2023-08-17 21:53:31 +00002248 mRE->drawLayers(settings, layers, mBuffer, base::unique_fd());
Patrick Williams2e9748f2022-08-09 22:48:18 +00002249 ASSERT_TRUE(futureOne.valid());
2250 auto resultOne = futureOne.get();
2251 ASSERT_TRUE(resultOne.ok());
2252 auto fenceOne = resultOne.value();
Sally Qi4cabdd02021-08-05 16:45:57 -07002253
Patrick Williams2e9748f2022-08-09 22:48:18 +00002254 ftl::Future<FenceResult> futureTwo =
Alec Mourif29700f2023-08-17 21:53:31 +00002255 mRE->drawLayers(settings, layers, mBuffer, base::unique_fd(fenceOne->dup()));
Patrick Williams2e9748f2022-08-09 22:48:18 +00002256 ASSERT_TRUE(futureTwo.valid());
2257 auto resultTwo = futureTwo.get();
2258 ASSERT_TRUE(resultTwo.ok());
2259 auto fenceTwo = resultTwo.value();
2260 fenceTwo->waitForever(LOG_TAG);
Derek Sollenbergerec411212021-08-25 10:54:47 -04002261
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002262 // Only cleanup the first time.
Ian Elliott1f0911e2022-09-09 16:31:47 -06002263 if (mRE->canSkipPostRenderCleanup()) {
2264 // Skia's Vk backend may keep the texture alive beyond drawLayersInternal, so
2265 // it never gets added to the cleanup list. In those cases, we can skip.
Leon Scroggins III696bf932024-01-24 15:21:05 -05002266 EXPECT_TRUE(GetParam()->graphicsApi() == renderengine::RenderEngine::GraphicsApi::VK);
Ian Elliott1f0911e2022-09-09 16:31:47 -06002267 } else {
2268 mRE->cleanupPostRender();
2269 EXPECT_TRUE(mRE->canSkipPostRenderCleanup());
2270 }
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002271}
2272
Ana Krulecf9a15d92020-12-11 08:35:00 -08002273TEST_P(RenderEngineTest, testRoundedCornersCrop) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002274 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002275 GTEST_SKIP();
2276 }
Alec Mouric0aae732021-01-12 13:32:18 -08002277 initializeRenderEngine();
Ana Krulecf9a15d92020-12-11 08:35:00 -08002278
2279 renderengine::DisplaySettings settings;
2280 settings.physicalDisplay = fullscreenRect();
2281 settings.clip = fullscreenRect();
2282 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2283
Sally Qi59a9f502021-10-12 18:53:23 +00002284 std::vector<renderengine::LayerSettings> layers;
Ana Krulecf9a15d92020-12-11 08:35:00 -08002285
2286 renderengine::LayerSettings redLayer;
2287 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2288 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002289 redLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
2290
Ana Krulecf9a15d92020-12-11 08:35:00 -08002291 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2292 // Red background.
2293 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2294 redLayer.alpha = 1.0f;
2295
Sally Qi59a9f502021-10-12 18:53:23 +00002296 layers.push_back(redLayer);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002297
2298 // Green layer with 1/3 size.
2299 renderengine::LayerSettings greenLayer;
2300 greenLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2301 greenLayer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002302 greenLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
Ana Krulecf9a15d92020-12-11 08:35:00 -08002303 // Bottom right corner is not going to be rounded.
2304 greenLayer.geometry.roundedCornersCrop =
2305 Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3, DEFAULT_DISPLAY_HEIGHT,
2306 DEFAULT_DISPLAY_HEIGHT)
2307 .toFloatRect();
2308 greenLayer.source.solidColor = half3(0.0f, 1.0f, 0.0f);
2309 greenLayer.alpha = 1.0f;
2310
Sally Qi59a9f502021-10-12 18:53:23 +00002311 layers.push_back(greenLayer);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002312
Alec Mouric0aae732021-01-12 13:32:18 -08002313 invokeDraw(settings, layers);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002314
2315 // Corners should be ignored...
2316 // Screen size: width is 128, height is 256.
2317 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 0);
2318 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, 0, DEFAULT_DISPLAY_WIDTH, 1), 0, 0, 0, 0);
2319 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT - 1, 1, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
2320 // Bottom right corner is kept out of the clipping, and it's green.
2321 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1,
2322 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
2323 0, 255, 0, 255);
2324}
2325
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002326TEST_P(RenderEngineTest, testRoundedCornersParentCrop) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002327 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002328 GTEST_SKIP();
2329 }
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002330 initializeRenderEngine();
2331
2332 renderengine::DisplaySettings settings;
2333 settings.physicalDisplay = fullscreenRect();
2334 settings.clip = fullscreenRect();
2335 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2336
Sally Qi59a9f502021-10-12 18:53:23 +00002337 std::vector<renderengine::LayerSettings> layers;
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002338
2339 renderengine::LayerSettings redLayer;
2340 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2341 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002342 redLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002343 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2344 // Red background.
2345 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2346 redLayer.alpha = 1.0f;
2347
Sally Qi59a9f502021-10-12 18:53:23 +00002348 layers.push_back(redLayer);
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002349
2350 // Green layer with 1/2 size with parent crop rect.
2351 renderengine::LayerSettings greenLayer = redLayer;
2352 greenLayer.geometry.boundaries =
2353 FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT / 2);
2354 greenLayer.source.solidColor = half3(0.0f, 1.0f, 0.0f);
2355
Sally Qi59a9f502021-10-12 18:53:23 +00002356 layers.push_back(greenLayer);
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002357
2358 invokeDraw(settings, layers);
2359
2360 // Due to roundedCornersRadius, the 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 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2364 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2365
2366 // top middle should be green and the bottom middle red
2367 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, 0), 0, 255, 0, 255);
2368 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0, 255);
2369
2370 // the bottom edge of the green layer should not be rounded
2371 expectBufferColor(Point(0, (DEFAULT_DISPLAY_HEIGHT / 2) - 1), 0, 255, 0, 255);
2372}
2373
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002374TEST_P(RenderEngineTest, testRoundedCornersParentCropSmallBounds) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002375 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002376 GTEST_SKIP();
2377 }
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002378 initializeRenderEngine();
2379
2380 renderengine::DisplaySettings settings;
2381 settings.physicalDisplay = fullscreenRect();
2382 settings.clip = fullscreenRect();
2383 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2384
Sally Qi59a9f502021-10-12 18:53:23 +00002385 std::vector<renderengine::LayerSettings> layers;
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002386
2387 renderengine::LayerSettings redLayer;
2388 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2389 redLayer.geometry.boundaries = FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, 32);
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002390 redLayer.geometry.roundedCornersRadius = {64.0f, 64.0f};
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002391 redLayer.geometry.roundedCornersCrop = FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, 128);
2392 // Red background.
2393 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2394 redLayer.alpha = 1.0f;
2395
Sally Qi59a9f502021-10-12 18:53:23 +00002396 layers.push_back(redLayer);
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002397 invokeDraw(settings, layers);
2398
2399 // Due to roundedCornersRadius, the top 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
2403 // ensure that the entire height of the red layer was clipped by the rounded corners crop.
2404 expectBufferColor(Point(0, 31), 0, 0, 0, 0);
2405 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 31), 0, 0, 0, 0);
2406
2407 // the bottom middle should be red
2408 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, 31), 255, 0, 0, 255);
2409}
2410
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002411TEST_P(RenderEngineTest, testRoundedCornersXY) {
Leon Scroggins III9ba31e32024-01-25 11:40:26 -05002412 if (!GetParam()->apiSupported()) {
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002413 GTEST_SKIP();
2414 }
2415
2416 initializeRenderEngine();
2417
2418 renderengine::DisplaySettings settings;
2419 settings.physicalDisplay = fullscreenRect();
2420 settings.clip = fullscreenRect();
2421 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2422
2423 std::vector<renderengine::LayerSettings> layers;
2424
2425 renderengine::LayerSettings redLayer;
2426 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2427 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
2428 redLayer.geometry.roundedCornersRadius = {5.0f, 20.0f};
2429 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2430 // Red background.
2431 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2432 redLayer.alpha = 1.0f;
2433
2434 layers.push_back(redLayer);
2435
2436 invokeDraw(settings, layers);
2437
2438 // Due to roundedCornersRadius, the corners are untouched.
2439 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2440 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2441 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2442 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2443
2444 // Y-axis draws a larger radius, check that its untouched as well
2445 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 5), 0, 0, 0, 0);
2446 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 5), 0, 0, 0, 0);
2447 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 5), 0, 0, 0, 0);
2448 expectBufferColor(Point(0, 5), 0, 0, 0, 0);
2449
2450 // middle should be red
2451 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0, 255);
2452}
2453
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002454TEST_P(RenderEngineTest, testClear) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002455 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002456 GTEST_SKIP();
2457 }
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002458 initializeRenderEngine();
2459
2460 const auto rect = fullscreenRect();
2461 const renderengine::DisplaySettings display{
2462 .physicalDisplay = rect,
2463 .clip = rect,
2464 };
2465
2466 const renderengine::LayerSettings redLayer{
2467 .geometry.boundaries = rect.toFloatRect(),
2468 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
2469 .alpha = 1.0f,
2470 };
2471
2472 // This mimics prepareClearClientComposition. This layer should overwrite
2473 // the redLayer, so that the buffer is transparent, rather than red.
2474 const renderengine::LayerSettings clearLayer{
2475 .geometry.boundaries = rect.toFloatRect(),
2476 .source.solidColor = half3(0.0f, 0.0f, 0.0f),
2477 .alpha = 0.0f,
2478 .disableBlending = true,
2479 };
2480
Sally Qi59a9f502021-10-12 18:53:23 +00002481 std::vector<renderengine::LayerSettings> layers{redLayer, clearLayer};
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002482 invokeDraw(display, layers);
2483 expectBufferColor(rect, 0, 0, 0, 0);
2484}
2485
2486TEST_P(RenderEngineTest, testDisableBlendingBuffer) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002487 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002488 GTEST_SKIP();
2489 }
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002490 initializeRenderEngine();
2491
2492 const auto rect = Rect(0, 0, 1, 1);
2493 const renderengine::DisplaySettings display{
2494 .physicalDisplay = rect,
2495 .clip = rect,
2496 };
2497
2498 const renderengine::LayerSettings redLayer{
2499 .geometry.boundaries = rect.toFloatRect(),
2500 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
2501 .alpha = 1.0f,
2502 };
2503
2504 // The next layer will overwrite redLayer with a GraphicBuffer that is green
2505 // applied with a translucent alpha.
Alec Mouria90a5702021-04-16 16:36:21 +00002506 const auto buf = allocateSourceBuffer(1, 1);
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002507 {
2508 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00002509 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2510 reinterpret_cast<void**>(&pixels));
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002511 pixels[0] = 0;
2512 pixels[1] = 255;
2513 pixels[2] = 0;
2514 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00002515 buf->getBuffer()->unlock();
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002516 }
2517
2518 const renderengine::LayerSettings greenLayer{
2519 .geometry.boundaries = rect.toFloatRect(),
2520 .source =
2521 renderengine::PixelSource{
2522 .buffer =
2523 renderengine::Buffer{
2524 .buffer = buf,
2525 .usePremultipliedAlpha = true,
2526 },
2527 },
2528 .alpha = 0.5f,
2529 .disableBlending = true,
2530 };
2531
Sally Qi59a9f502021-10-12 18:53:23 +00002532 std::vector<renderengine::LayerSettings> layers{redLayer, greenLayer};
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002533 invokeDraw(display, layers);
2534 expectBufferColor(rect, 0, 128, 0, 128);
2535}
2536
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002537TEST_P(RenderEngineTest, testDimming) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002538 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002539 GTEST_SKIP();
2540 }
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002541 initializeRenderEngine();
2542
Alec Mouri85065692022-03-18 00:58:26 +00002543 const ui::Dataspace dataspace = ui::Dataspace::V0_SRGB_LINEAR;
2544
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002545 const auto displayRect = Rect(3, 1);
2546 const renderengine::DisplaySettings display{
2547 .physicalDisplay = displayRect,
2548 .clip = displayRect,
Alec Mouri85065692022-03-18 00:58:26 +00002549 .outputDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002550 .targetLuminanceNits = 1000.f,
2551 };
2552
2553 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2554 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2555 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2556
2557 const renderengine::LayerSettings greenLayer{
2558 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2559 .source =
2560 renderengine::PixelSource{
2561 .buffer =
2562 renderengine::Buffer{
2563 .buffer = greenBuffer,
2564 .usePremultipliedAlpha = true,
2565 },
2566 },
2567 .alpha = 1.0f,
Alec Mouri85065692022-03-18 00:58:26 +00002568 .sourceDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002569 .whitePointNits = 200.f,
2570 };
2571
2572 const renderengine::LayerSettings blueLayer{
2573 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2574 .source =
2575 renderengine::PixelSource{
2576 .buffer =
2577 renderengine::Buffer{
2578 .buffer = blueBuffer,
2579 .usePremultipliedAlpha = true,
2580 },
2581 },
2582 .alpha = 1.0f,
Alec Mouri85065692022-03-18 00:58:26 +00002583 .sourceDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002584 .whitePointNits = 1000.f / 51.f,
2585 };
2586
2587 const renderengine::LayerSettings redLayer{
2588 .geometry.boundaries = FloatRect(2.f, 0.f, 3.f, 1.f),
2589 .source =
2590 renderengine::PixelSource{
2591 .buffer =
2592 renderengine::Buffer{
2593 .buffer = redBuffer,
2594 .usePremultipliedAlpha = true,
2595 },
2596 },
2597 .alpha = 1.0f,
Alec Mouri85065692022-03-18 00:58:26 +00002598 .sourceDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002599 // When the white point is not set for a layer, just ignore it and treat it as the same
2600 // as the max layer
2601 .whitePointNits = -1.f,
2602 };
2603
2604 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer, redLayer};
2605 invokeDraw(display, layers);
2606
2607 expectBufferColor(Rect(1, 1), 0, 51, 0, 255, 1);
2608 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 5, 255, 1);
2609 expectBufferColor(Rect(2, 0, 3, 1), 51, 0, 0, 255, 1);
2610}
2611
Alec Mouri85065692022-03-18 00:58:26 +00002612TEST_P(RenderEngineTest, testDimming_inGammaSpace) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002613 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002614 GTEST_SKIP();
2615 }
Alec Mouri85065692022-03-18 00:58:26 +00002616 initializeRenderEngine();
2617
2618 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2619 ui::Dataspace::TRANSFER_GAMMA2_2 |
2620 ui::Dataspace::RANGE_FULL);
2621
2622 const auto displayRect = Rect(3, 1);
2623 const renderengine::DisplaySettings display{
2624 .physicalDisplay = displayRect,
2625 .clip = displayRect,
2626 .outputDataspace = dataspace,
2627 .targetLuminanceNits = 1000.f,
2628 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2629 };
2630
2631 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2632 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2633 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2634
2635 const renderengine::LayerSettings greenLayer{
2636 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2637 .source =
2638 renderengine::PixelSource{
2639 .buffer =
2640 renderengine::Buffer{
2641 .buffer = greenBuffer,
2642 .usePremultipliedAlpha = true,
2643 },
2644 },
2645 .alpha = 1.0f,
2646 .sourceDataspace = dataspace,
2647 .whitePointNits = 200.f,
2648 };
2649
2650 const renderengine::LayerSettings blueLayer{
2651 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2652 .source =
2653 renderengine::PixelSource{
2654 .buffer =
2655 renderengine::Buffer{
2656 .buffer = blueBuffer,
2657 .usePremultipliedAlpha = true,
2658 },
2659 },
2660 .alpha = 1.0f,
2661 .sourceDataspace = dataspace,
2662 .whitePointNits = 1000.f / 51.f,
2663 };
2664
2665 const renderengine::LayerSettings redLayer{
2666 .geometry.boundaries = FloatRect(2.f, 0.f, 3.f, 1.f),
2667 .source =
2668 renderengine::PixelSource{
2669 .buffer =
2670 renderengine::Buffer{
2671 .buffer = redBuffer,
2672 .usePremultipliedAlpha = true,
2673 },
2674 },
2675 .alpha = 1.0f,
2676 .sourceDataspace = dataspace,
2677 // When the white point is not set for a layer, just ignore it and treat it as the same
2678 // as the max layer
2679 .whitePointNits = -1.f,
2680 };
2681
2682 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer, redLayer};
2683 invokeDraw(display, layers);
2684
2685 expectBufferColor(Rect(1, 1), 0, 122, 0, 255, 1);
2686 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 42, 255, 1);
2687 expectBufferColor(Rect(2, 0, 3, 1), 122, 0, 0, 255, 1);
2688}
2689
Alec Mouri9bcd1d12022-04-21 22:16:56 +00002690TEST_P(RenderEngineTest, testDimming_inGammaSpace_withDisplayColorTransform) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002691 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002692 GTEST_SKIP();
2693 }
Alec Mouri9bcd1d12022-04-21 22:16:56 +00002694 initializeRenderEngine();
2695
2696 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2697 ui::Dataspace::TRANSFER_GAMMA2_2 |
2698 ui::Dataspace::RANGE_FULL);
2699
2700 const auto displayRect = Rect(3, 1);
2701 const renderengine::DisplaySettings display{
2702 .physicalDisplay = displayRect,
2703 .clip = displayRect,
2704 .outputDataspace = dataspace,
2705 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
2706 .targetLuminanceNits = 1000.f,
2707 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2708 };
2709
2710 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2711 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2712 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2713
2714 const renderengine::LayerSettings greenLayer{
2715 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2716 .source =
2717 renderengine::PixelSource{
2718 .buffer =
2719 renderengine::Buffer{
2720 .buffer = greenBuffer,
2721 .usePremultipliedAlpha = true,
2722 },
2723 },
2724 .alpha = 1.0f,
2725 .sourceDataspace = dataspace,
2726 .whitePointNits = 200.f,
2727 };
2728
2729 const renderengine::LayerSettings redLayer{
2730 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2731 .source =
2732 renderengine::PixelSource{
2733 .buffer =
2734 renderengine::Buffer{
2735 .buffer = redBuffer,
2736 .usePremultipliedAlpha = true,
2737 },
2738 },
2739 .alpha = 1.0f,
2740 .sourceDataspace = dataspace,
2741 // When the white point is not set for a layer, just ignore it and treat it as the same
2742 // as the max layer
2743 .whitePointNits = -1.f,
2744 };
2745
2746 std::vector<renderengine::LayerSettings> layers{greenLayer, redLayer};
2747 invokeDraw(display, layers);
2748
2749 expectBufferColor(Rect(1, 1), 0, 0, 0, 255, 1);
2750 expectBufferColor(Rect(1, 0, 2, 1), 0, 122, 0, 255, 1);
2751}
2752
2753TEST_P(RenderEngineTest, testDimming_inGammaSpace_withDisplayColorTransform_deviceHandles) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002754 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002755 GTEST_SKIP();
2756 }
Alec Mouri9bcd1d12022-04-21 22:16:56 +00002757 initializeRenderEngine();
2758
2759 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2760 ui::Dataspace::TRANSFER_GAMMA2_2 |
2761 ui::Dataspace::RANGE_FULL);
2762
2763 const auto displayRect = Rect(3, 1);
2764 const renderengine::DisplaySettings display{
2765 .physicalDisplay = displayRect,
2766 .clip = displayRect,
2767 .outputDataspace = dataspace,
2768 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
2769 .deviceHandlesColorTransform = true,
2770 .targetLuminanceNits = 1000.f,
2771 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2772 };
2773
2774 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2775 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2776 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2777
2778 const renderengine::LayerSettings greenLayer{
2779 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2780 .source =
2781 renderengine::PixelSource{
2782 .buffer =
2783 renderengine::Buffer{
2784 .buffer = greenBuffer,
2785 .usePremultipliedAlpha = true,
2786 },
2787 },
2788 .alpha = 1.0f,
2789 .sourceDataspace = dataspace,
2790 .whitePointNits = 200.f,
2791 };
2792
2793 const renderengine::LayerSettings redLayer{
2794 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2795 .source =
2796 renderengine::PixelSource{
2797 .buffer =
2798 renderengine::Buffer{
2799 .buffer = redBuffer,
2800 .usePremultipliedAlpha = true,
2801 },
2802 },
2803 .alpha = 1.0f,
2804 .sourceDataspace = dataspace,
2805 // When the white point is not set for a layer, just ignore it and treat it as the same
2806 // as the max layer
2807 .whitePointNits = -1.f,
2808 };
2809
2810 std::vector<renderengine::LayerSettings> layers{greenLayer, redLayer};
2811 invokeDraw(display, layers);
2812
2813 expectBufferColor(Rect(1, 1), 0, 122, 0, 255, 1);
2814 expectBufferColor(Rect(1, 0, 2, 1), 122, 0, 0, 255, 1);
2815}
2816
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002817TEST_P(RenderEngineTest, testDimming_withoutTargetLuminance) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002818 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002819 GTEST_SKIP();
2820 }
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002821 initializeRenderEngine();
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002822
2823 const auto displayRect = Rect(2, 1);
2824 const renderengine::DisplaySettings display{
2825 .physicalDisplay = displayRect,
2826 .clip = displayRect,
2827 .outputDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2828 .targetLuminanceNits = -1.f,
2829 };
2830
2831 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2832 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2833
2834 const renderengine::LayerSettings greenLayer{
2835 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2836 .source =
2837 renderengine::PixelSource{
2838 .buffer =
2839 renderengine::Buffer{
2840 .buffer = greenBuffer,
2841 .usePremultipliedAlpha = true,
2842 },
2843 },
2844 .alpha = 1.0f,
2845 .sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2846 .whitePointNits = 200.f,
2847 };
2848
2849 const renderengine::LayerSettings blueLayer{
2850 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2851 .source =
2852 renderengine::PixelSource{
2853 .buffer =
2854 renderengine::Buffer{
2855 .buffer = blueBuffer,
2856 .usePremultipliedAlpha = true,
2857 },
2858 },
2859 .alpha = 1.0f,
2860 .sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2861 .whitePointNits = 1000.f,
2862 };
2863
2864 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer};
2865 invokeDraw(display, layers);
2866
2867 expectBufferColor(Rect(1, 1), 0, 51, 0, 255, 1);
2868 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 255, 255);
2869}
2870
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002871TEST_P(RenderEngineTest, test_isOpaque) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002872 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002873 GTEST_SKIP();
2874 }
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002875 initializeRenderEngine();
2876
2877 const auto rect = Rect(0, 0, 1, 1);
2878 const renderengine::DisplaySettings display{
2879 .physicalDisplay = rect,
2880 .clip = rect,
2881 .outputDataspace = ui::Dataspace::DISPLAY_P3,
2882 };
2883
2884 // Create an unpremul buffer that is green with no alpha. Using isOpaque
2885 // should make the green show.
2886 const auto buf = allocateSourceBuffer(1, 1);
2887 {
2888 uint8_t* pixels;
2889 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2890 reinterpret_cast<void**>(&pixels));
2891 pixels[0] = 0;
2892 pixels[1] = 255;
2893 pixels[2] = 0;
2894 pixels[3] = 0;
2895 buf->getBuffer()->unlock();
2896 }
2897
2898 const renderengine::LayerSettings greenLayer{
2899 .geometry.boundaries = rect.toFloatRect(),
2900 .source =
2901 renderengine::PixelSource{
2902 .buffer =
2903 renderengine::Buffer{
2904 .buffer = buf,
2905 // Although the pixels are not
2906 // premultiplied in practice, this
2907 // matches the input we see.
2908 .usePremultipliedAlpha = true,
2909 .isOpaque = true,
2910 },
2911 },
2912 .alpha = 1.0f,
2913 };
2914
Sally Qi59a9f502021-10-12 18:53:23 +00002915 std::vector<renderengine::LayerSettings> layers{greenLayer};
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002916 invokeDraw(display, layers);
2917
Alec Mouri47bcb072023-08-15 02:02:49 +00002918 expectBufferColor(rect, 117, 251, 76, 255);
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002919}
Alec Mouri4049b532021-10-15 20:59:33 -07002920
Alec Mouri4049b532021-10-15 20:59:33 -07002921TEST_P(RenderEngineTest, test_tonemapPQMatches) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002922 if (!GetParam()->apiSupported()) {
Alec Mouri5a493722022-01-26 16:43:02 -08002923 GTEST_SKIP();
Alec Mouri4049b532021-10-15 20:59:33 -07002924 }
2925
Alec Mouri4049b532021-10-15 20:59:33 -07002926 initializeRenderEngine();
2927
Alec Mouri5a493722022-01-26 16:43:02 -08002928 tonemap(
2929 static_cast<ui::Dataspace>(HAL_DATASPACE_STANDARD_BT2020 |
2930 HAL_DATASPACE_TRANSFER_ST2084 | HAL_DATASPACE_RANGE_FULL),
2931 [](vec3 color) { return EOTF_PQ(color); },
2932 [](vec3 color, float) {
2933 static constexpr float kMaxPQLuminance = 10000.f;
2934 return color * kMaxPQLuminance;
2935 });
2936}
Alec Mouri4049b532021-10-15 20:59:33 -07002937
Alec Mouri5a493722022-01-26 16:43:02 -08002938TEST_P(RenderEngineTest, test_tonemapHLGMatches) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002939 if (!GetParam()->apiSupported()) {
Alec Mouri5a493722022-01-26 16:43:02 -08002940 GTEST_SKIP();
Alec Mouri4049b532021-10-15 20:59:33 -07002941 }
2942
Alec Mouri5a493722022-01-26 16:43:02 -08002943 initializeRenderEngine();
Alec Mouri4049b532021-10-15 20:59:33 -07002944
Alec Mouri5a493722022-01-26 16:43:02 -08002945 tonemap(
2946 static_cast<ui::Dataspace>(HAL_DATASPACE_STANDARD_BT2020 | HAL_DATASPACE_TRANSFER_HLG |
2947 HAL_DATASPACE_RANGE_FULL),
2948 [](vec3 color) { return EOTF_HLG(color); },
2949 [](vec3 color, float currentLuminaceNits) {
2950 static constexpr float kMaxHLGLuminance = 1000.f;
Alec Mouri7a577452022-03-04 23:41:38 +00002951 return color * kMaxHLGLuminance;
Alec Mouri5a493722022-01-26 16:43:02 -08002952 });
Alec Mouri4049b532021-10-15 20:59:33 -07002953}
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -05002954
2955TEST_P(RenderEngineTest, r8_behaves_as_mask) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002956 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002957 GTEST_SKIP();
2958 }
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -05002959 initializeRenderEngine();
2960
2961 const auto r8Buffer = allocateR8Buffer(2, 1);
2962 if (!r8Buffer) {
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05002963 GTEST_SKIP() << "Test is only necessary on devices that support r8";
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -05002964 return;
2965 }
2966 {
2967 uint8_t* pixels;
2968 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2969 reinterpret_cast<void**>(&pixels));
2970 // This will be drawn on top of a green buffer. We'll verify that 255
2971 // results in keeping the original green and 0 results in black.
2972 pixels[0] = 0;
2973 pixels[1] = 255;
2974 r8Buffer->getBuffer()->unlock();
2975 }
2976
2977 const auto rect = Rect(0, 0, 2, 1);
2978 const renderengine::DisplaySettings display{
2979 .physicalDisplay = rect,
2980 .clip = rect,
2981 .outputDataspace = ui::Dataspace::SRGB,
2982 };
2983
2984 const auto greenBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(0, 255, 0, 255));
2985 const renderengine::LayerSettings greenLayer{
2986 .geometry.boundaries = rect.toFloatRect(),
2987 .source =
2988 renderengine::PixelSource{
2989 .buffer =
2990 renderengine::Buffer{
2991 .buffer = greenBuffer,
2992 },
2993 },
2994 .alpha = 1.0f,
2995 };
2996 const renderengine::LayerSettings r8Layer{
2997 .geometry.boundaries = rect.toFloatRect(),
2998 .source =
2999 renderengine::PixelSource{
3000 .buffer =
3001 renderengine::Buffer{
3002 .buffer = r8Buffer,
3003 },
3004 },
3005 .alpha = 1.0f,
3006 };
3007
3008 std::vector<renderengine::LayerSettings> layers{greenLayer, r8Layer};
3009 invokeDraw(display, layers);
3010
3011 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 255);
3012 expectBufferColor(Rect(1, 0, 2, 1), 0, 255, 0, 255);
3013}
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003014
3015TEST_P(RenderEngineTest, r8_respects_color_transform) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05003016 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003017 GTEST_SKIP();
3018 }
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003019 initializeRenderEngine();
3020
3021 const auto r8Buffer = allocateR8Buffer(2, 1);
3022 if (!r8Buffer) {
3023 GTEST_SKIP() << "Test is only necessary on devices that support r8";
3024 return;
3025 }
3026 {
3027 uint8_t* pixels;
3028 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
3029 reinterpret_cast<void**>(&pixels));
3030 pixels[0] = 0;
3031 pixels[1] = 255;
3032 r8Buffer->getBuffer()->unlock();
3033 }
3034
3035 const auto rect = Rect(0, 0, 2, 1);
3036 const renderengine::DisplaySettings display{
3037 .physicalDisplay = rect,
3038 .clip = rect,
3039 .outputDataspace = ui::Dataspace::SRGB,
3040 // Verify that the R8 layer respects the color transform when
3041 // deviceHandlesColorTransform is false. This transform converts
3042 // pure red to pure green. That will occur when the R8 buffer is
3043 // 255. When the R8 buffer is 0, it will still change to black, as
3044 // with r8_behaves_as_mask.
Alec Mouri9bcd1d12022-04-21 22:16:56 +00003045 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003046 .deviceHandlesColorTransform = false,
3047 };
3048
3049 const auto redBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(255, 0, 0, 255));
3050 const renderengine::LayerSettings redLayer{
3051 .geometry.boundaries = rect.toFloatRect(),
3052 .source =
3053 renderengine::PixelSource{
3054 .buffer =
3055 renderengine::Buffer{
3056 .buffer = redBuffer,
3057 },
3058 },
3059 .alpha = 1.0f,
3060 };
3061 const renderengine::LayerSettings r8Layer{
3062 .geometry.boundaries = rect.toFloatRect(),
3063 .source =
3064 renderengine::PixelSource{
3065 .buffer =
3066 renderengine::Buffer{
3067 .buffer = r8Buffer,
3068 },
3069 },
3070 .alpha = 1.0f,
3071 };
3072
3073 std::vector<renderengine::LayerSettings> layers{redLayer, r8Layer};
3074 invokeDraw(display, layers);
3075
3076 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 255);
3077 expectBufferColor(Rect(1, 0, 2, 1), 0, 255, 0, 255);
3078}
3079
3080TEST_P(RenderEngineTest, r8_respects_color_transform_when_device_handles) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05003081 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003082 GTEST_SKIP();
3083 }
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003084 initializeRenderEngine();
3085
3086 const auto r8Buffer = allocateR8Buffer(2, 1);
3087 if (!r8Buffer) {
3088 GTEST_SKIP() << "Test is only necessary on devices that support r8";
3089 return;
3090 }
3091 {
3092 uint8_t* pixels;
3093 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
3094 reinterpret_cast<void**>(&pixels));
3095 pixels[0] = 0;
3096 pixels[1] = 255;
3097 r8Buffer->getBuffer()->unlock();
3098 }
3099
3100 const auto rect = Rect(0, 0, 2, 1);
3101 const renderengine::DisplaySettings display{
3102 .physicalDisplay = rect,
3103 .clip = rect,
3104 .outputDataspace = ui::Dataspace::SRGB,
3105 // If deviceHandlesColorTransform is true, pixels where the A8
3106 // buffer is opaque are unaffected. If the colorTransform is
3107 // invertible, pixels where the A8 buffer are transparent have the
3108 // inverse applied to them so that the DPU will convert them back to
3109 // black. Test with an arbitrary, invertible matrix.
3110 .colorTransform = mat4(1, 0, 0, 2,
3111 3, 1, 2, 5,
3112 0, 5, 3, 0,
3113 0, 1, 0, 2),
3114 .deviceHandlesColorTransform = true,
3115 };
3116
3117 const auto redBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(255, 0, 0, 255));
3118 const renderengine::LayerSettings redLayer{
3119 .geometry.boundaries = rect.toFloatRect(),
3120 .source =
3121 renderengine::PixelSource{
3122 .buffer =
3123 renderengine::Buffer{
3124 .buffer = redBuffer,
3125 },
3126 },
3127 .alpha = 1.0f,
3128 };
3129 const renderengine::LayerSettings r8Layer{
3130 .geometry.boundaries = rect.toFloatRect(),
3131 .source =
3132 renderengine::PixelSource{
3133 .buffer =
3134 renderengine::Buffer{
3135 .buffer = r8Buffer,
3136 },
3137 },
3138 .alpha = 1.0f,
3139 };
3140
3141 std::vector<renderengine::LayerSettings> layers{redLayer, r8Layer};
3142 invokeDraw(display, layers);
3143
3144 expectBufferColor(Rect(1, 0, 2, 1), 255, 0, 0, 255); // Still red.
3145 expectBufferColor(Rect(0, 0, 1, 1), 0, 70, 0, 255);
3146}
Leon Scroggins III45be9182022-04-27 10:37:11 -04003147
3148TEST_P(RenderEngineTest, primeShaderCache) {
Nolan Scobie195631a2024-03-26 12:22:23 -04003149 // TODO: b/331447071 - Fix in Graphite and re-enable.
3150 if (GetParam()->skiaBackend() == renderengine::RenderEngine::SkiaBackend::GRAPHITE) {
3151 GTEST_SKIP();
3152 }
3153
Leon Scroggins III696bf932024-01-24 15:21:05 -05003154 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003155 GTEST_SKIP();
3156 }
Leon Scroggins III45be9182022-04-27 10:37:11 -04003157 initializeRenderEngine();
3158
Bruno BELANYIb9b5b702023-10-13 13:25:11 +00003159 auto fut = mRE->primeCache(false);
Leon Scroggins III45be9182022-04-27 10:37:11 -04003160 if (fut.valid()) {
3161 fut.wait();
3162 }
3163
Alec Mouri47bcb072023-08-15 02:02:49 +00003164 static constexpr int kMinimumExpectedShadersCompiled = 60;
Leon Scroggins III45be9182022-04-27 10:37:11 -04003165 ASSERT_GT(static_cast<skia::SkiaGLRenderEngine*>(mRE.get())->reportShadersCompiled(),
Alec Mouri47bcb072023-08-15 02:02:49 +00003166 kMinimumExpectedShadersCompiled);
Leon Scroggins III45be9182022-04-27 10:37:11 -04003167}
Derek Sollenbergerd3f60652021-06-11 15:34:36 -04003168} // namespace renderengine
Alec Mouri6e57f682018-09-29 20:45:08 -07003169} // namespace android
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08003170
3171// TODO(b/129481165): remove the #pragma below and fix conversion issues
Marin Shalamanovbed7fd32020-12-21 20:02:20 +01003172#pragma clang diagnostic pop // ignored "-Wconversion -Wextra"