blob: 7b8eb8470f7bb5940b2de532064b2b9e815428d1 [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;
Leon Scroggins IIIf3369ed2024-02-16 17:52:42 -0500110 bool apiSupported() { return renderengine::RenderEngine::canSupport(graphicsApi()); }
Leon Scroggins III5ef55002024-01-25 10:51:45 -0500111 std::unique_ptr<renderengine::RenderEngine> createRenderEngine() {
112 renderengine::RenderEngineCreationArgs reCreationArgs =
113 renderengine::RenderEngineCreationArgs::Builder()
114 .setPixelFormat(static_cast<int>(ui::PixelFormat::RGBA_8888))
115 .setImageCacheSize(1)
116 .setEnableProtectedContext(false)
117 .setPrecacheToneMapperShaderOnly(false)
118 .setSupportsBackgroundBlur(true)
119 .setContextPriority(renderengine::RenderEngine::ContextPriority::MEDIUM)
Leon Scroggins III696bf932024-01-24 15:21:05 -0500120 .setThreaded(renderengine::RenderEngine::Threaded::NO)
121 .setGraphicsApi(graphicsApi())
Leon Scroggins III5ef55002024-01-25 10:51:45 -0500122 .build();
123 return renderengine::RenderEngine::create(reCreationArgs);
124 }
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800125};
126
Ian Elliott1f0911e2022-09-09 16:31:47 -0600127class SkiaVkRenderEngineFactory : public RenderEngineFactory {
128public:
129 std::string name() override { return "SkiaVkRenderEngineFactory"; }
130
Leon Scroggins III696bf932024-01-24 15:21:05 -0500131 renderengine::RenderEngine::GraphicsApi graphicsApi() override {
132 return renderengine::RenderEngine::GraphicsApi::VK;
Ian Elliott1f0911e2022-09-09 16:31:47 -0600133 }
Ian Elliott1f0911e2022-09-09 16:31:47 -0600134};
135
Alec Mouri0eab3e82020-12-08 18:10:27 -0800136class SkiaGLESRenderEngineFactory : public RenderEngineFactory {
137public:
Alec Mouric0aae732021-01-12 13:32:18 -0800138 std::string name() override { return "SkiaGLRenderEngineFactory"; }
Alec Mouri0eab3e82020-12-08 18:10:27 -0800139
Leon Scroggins III696bf932024-01-24 15:21:05 -0500140 renderengine::RenderEngine::GraphicsApi graphicsApi() {
141 return renderengine::RenderEngine::GraphicsApi::GL;
Alec Mouric0aae732021-01-12 13:32:18 -0800142 }
Alec Mouri0eab3e82020-12-08 18:10:27 -0800143};
144
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800145class RenderEngineTest : public ::testing::TestWithParam<std::shared_ptr<RenderEngineFactory>> {
146public:
Alec Mouria90a5702021-04-16 16:36:21 +0000147 std::shared_ptr<renderengine::ExternalTexture> allocateDefaultBuffer() {
148 return std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800149 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -0700150 ExternalTexture>(sp<GraphicBuffer>::
151 make(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT,
152 HAL_PIXEL_FORMAT_RGBA_8888, 1,
153 GRALLOC_USAGE_SW_READ_OFTEN |
154 GRALLOC_USAGE_SW_WRITE_OFTEN |
155 GRALLOC_USAGE_HW_RENDER |
156 GRALLOC_USAGE_HW_TEXTURE,
157 "output"),
Alec Mouria90a5702021-04-16 16:36:21 +0000158 *mRE,
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800159 renderengine::impl::ExternalTexture::Usage::READABLE |
160 renderengine::impl::ExternalTexture::Usage::
161 WRITEABLE);
Alec Mouri6e57f682018-09-29 20:45:08 -0700162 }
163
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800164 // Allocates a 1x1 buffer to fill with a solid color
Alec Mouria90a5702021-04-16 16:36:21 +0000165 std::shared_ptr<renderengine::ExternalTexture> allocateSourceBuffer(uint32_t width,
166 uint32_t height) {
167 return std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800168 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -0700169 ExternalTexture>(sp<GraphicBuffer>::
170 make(width, height, HAL_PIXEL_FORMAT_RGBA_8888, 1,
171 GRALLOC_USAGE_SW_READ_OFTEN |
172 GRALLOC_USAGE_SW_WRITE_OFTEN |
173 GRALLOC_USAGE_HW_TEXTURE,
174 "input"),
Alec Mouria90a5702021-04-16 16:36:21 +0000175 *mRE,
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800176 renderengine::impl::ExternalTexture::Usage::READABLE |
177 renderengine::impl::ExternalTexture::Usage::
178 WRITEABLE);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800179 }
180
Alec Mouricdf6cbc2021-11-01 17:21:15 -0700181 std::shared_ptr<renderengine::ExternalTexture> allocateAndFillSourceBuffer(uint32_t width,
182 uint32_t height,
183 ubyte4 color) {
184 const auto buffer = allocateSourceBuffer(width, height);
185 uint8_t* pixels;
186 buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
187 reinterpret_cast<void**>(&pixels));
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -0500188 for (uint32_t j = 0; j < height; j++) {
189 uint8_t* dst = pixels + (buffer->getBuffer()->getStride() * j * 4);
190 for (uint32_t i = 0; i < width; i++) {
191 dst[0] = color.r;
192 dst[1] = color.g;
193 dst[2] = color.b;
194 dst[3] = color.a;
195 dst += 4;
196 }
197 }
Alec Mouricdf6cbc2021-11-01 17:21:15 -0700198 buffer->getBuffer()->unlock();
199 return buffer;
200 }
201
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -0500202 std::shared_ptr<renderengine::ExternalTexture> allocateR8Buffer(int width, int height) {
Ady Abrahamd11bade2022-08-01 16:18:03 -0700203 const auto kUsageFlags =
204 static_cast<uint64_t>(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
205 GRALLOC_USAGE_HW_TEXTURE);
206 auto buffer =
207 sp<GraphicBuffer>::make(static_cast<uint32_t>(width), static_cast<uint32_t>(height),
208 android::PIXEL_FORMAT_R_8, 1u, kUsageFlags, "r8");
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -0500209 if (buffer->initCheck() != 0) {
210 // Devices are not required to support R8.
211 return nullptr;
212 }
213 return std::make_shared<
214 renderengine::impl::ExternalTexture>(std::move(buffer), *mRE,
215 renderengine::impl::ExternalTexture::Usage::
216 READABLE);
217 }
218
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800219 RenderEngineTest() {
220 const ::testing::TestInfo* const test_info =
221 ::testing::UnitTest::GetInstance()->current_test_info();
222 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800223 }
Alec Mouri1089aed2018-10-25 21:33:57 -0700224
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800225 ~RenderEngineTest() {
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800226 if (WRITE_BUFFER_TO_FILE_ON_FAILURE && ::testing::Test::HasFailure()) {
227 writeBufferToFile("/data/texture_out_");
228 }
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800229 const ::testing::TestInfo* const test_info =
230 ::testing::UnitTest::GetInstance()->current_test_info();
231 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800232 }
233
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800234 void writeBufferToFile(const char* basename) {
235 std::string filename(basename);
236 filename.append(::testing::UnitTest::GetInstance()->current_test_info()->name());
237 filename.append(".ppm");
238 std::ofstream file(filename.c_str(), std::ios::binary);
239 if (!file.is_open()) {
240 ALOGE("Unable to open file: %s", filename.c_str());
241 ALOGE("You may need to do: \"adb shell setenforce 0\" to enable "
242 "surfaceflinger to write debug images");
243 return;
244 }
245
Alec Mouri1089aed2018-10-25 21:33:57 -0700246 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +0000247 mBuffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
248 reinterpret_cast<void**>(&pixels));
Alec Mouri1089aed2018-10-25 21:33:57 -0700249
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800250 file << "P6\n";
Alec Mouria90a5702021-04-16 16:36:21 +0000251 file << mBuffer->getBuffer()->getWidth() << "\n";
252 file << mBuffer->getBuffer()->getHeight() << "\n";
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800253 file << 255 << "\n";
254
Alec Mouria90a5702021-04-16 16:36:21 +0000255 std::vector<uint8_t> outBuffer(mBuffer->getBuffer()->getWidth() *
256 mBuffer->getBuffer()->getHeight() * 3);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800257 auto outPtr = reinterpret_cast<uint8_t*>(outBuffer.data());
258
Alec Mouria90a5702021-04-16 16:36:21 +0000259 for (int32_t j = 0; j < mBuffer->getBuffer()->getHeight(); j++) {
260 const uint8_t* src = pixels + (mBuffer->getBuffer()->getStride() * j) * 4;
261 for (int32_t i = 0; i < mBuffer->getBuffer()->getWidth(); i++) {
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800262 // Only copy R, G and B components
263 outPtr[0] = src[0];
264 outPtr[1] = src[1];
265 outPtr[2] = src[2];
266 outPtr += 3;
267
268 src += 4;
269 }
270 }
271 file.write(reinterpret_cast<char*>(outBuffer.data()), outBuffer.size());
Alec Mouria90a5702021-04-16 16:36:21 +0000272 mBuffer->getBuffer()->unlock();
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800273 }
274
275 void expectBufferColor(const Region& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
276 size_t c;
277 Rect const* rect = region.getArray(&c);
278 for (size_t i = 0; i < c; i++, rect++) {
279 expectBufferColor(*rect, r, g, b, a);
280 }
281 }
282
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -0400283 void expectBufferColor(const Point& point, uint8_t r, uint8_t g, uint8_t b, uint8_t a,
284 uint8_t tolerance = 0) {
285 expectBufferColor(Rect(point.x, point.y, point.x + 1, point.y + 1), r, g, b, a, tolerance);
286 }
287
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800288 void expectBufferColor(const Rect& rect, uint8_t r, uint8_t g, uint8_t b, uint8_t a,
289 uint8_t tolerance = 0) {
Alec Mouri4049b532021-10-15 20:59:33 -0700290 auto generator = [=](Point) { return ubyte4(r, g, b, a); };
291 expectBufferColor(rect, generator, tolerance);
292 }
293
294 using ColorGenerator = std::function<ubyte4(Point location)>;
295
296 void expectBufferColor(const Rect& rect, ColorGenerator generator, uint8_t tolerance = 0) {
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800297 auto colorCompare = [tolerance](const uint8_t* colorA, const uint8_t* colorB) {
298 auto colorBitCompare = [tolerance](uint8_t a, uint8_t b) {
299 uint8_t tmp = a >= b ? a - b : b - a;
300 return tmp <= tolerance;
301 };
302 return std::equal(colorA, colorA + 4, colorB, colorBitCompare);
Alec Mouri1089aed2018-10-25 21:33:57 -0700303 };
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800304
Alec Mouri4049b532021-10-15 20:59:33 -0700305 expectBufferColor(rect, generator, colorCompare);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800306 }
307
Alec Mouri4049b532021-10-15 20:59:33 -0700308 void expectBufferColor(const Rect& region, ColorGenerator generator,
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800309 std::function<bool(const uint8_t* a, const uint8_t* b)> colorCompare) {
310 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +0000311 mBuffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
312 reinterpret_cast<void**>(&pixels));
Alec Mouri1089aed2018-10-25 21:33:57 -0700313 int32_t maxFails = 10;
314 int32_t fails = 0;
315 for (int32_t j = 0; j < region.getHeight(); j++) {
Alec Mouria90a5702021-04-16 16:36:21 +0000316 const uint8_t* src = pixels +
317 (mBuffer->getBuffer()->getStride() * (region.top + j) + region.left) * 4;
Alec Mouri1089aed2018-10-25 21:33:57 -0700318 for (int32_t i = 0; i < region.getWidth(); i++) {
Alec Mouri4049b532021-10-15 20:59:33 -0700319 const auto location = Point(region.left + i, region.top + j);
320 const ubyte4 colors = generator(location);
321 const uint8_t expected[4] = {colors.r, colors.g, colors.b, colors.a};
322 bool colorMatches = colorCompare(src, expected);
323 EXPECT_TRUE(colorMatches)
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -0400324 << GetParam()->name().c_str() << ": "
Alec Mouri4049b532021-10-15 20:59:33 -0700325 << "pixel @ (" << location.x << ", " << location.y << "): "
326 << "expected (" << static_cast<uint32_t>(colors.r) << ", "
327 << static_cast<uint32_t>(colors.g) << ", "
328 << static_cast<uint32_t>(colors.b) << ", "
329 << static_cast<uint32_t>(colors.a) << "), "
Alec Mouri1089aed2018-10-25 21:33:57 -0700330 << "got (" << static_cast<uint32_t>(src[0]) << ", "
331 << static_cast<uint32_t>(src[1]) << ", " << static_cast<uint32_t>(src[2])
332 << ", " << static_cast<uint32_t>(src[3]) << ")";
333 src += 4;
Alec Mouri4049b532021-10-15 20:59:33 -0700334 if (!colorMatches && ++fails >= maxFails) {
Alec Mouri1089aed2018-10-25 21:33:57 -0700335 break;
336 }
337 }
338 if (fails >= maxFails) {
339 break;
340 }
341 }
Alec Mouria90a5702021-04-16 16:36:21 +0000342 mBuffer->getBuffer()->unlock();
Alec Mouri1089aed2018-10-25 21:33:57 -0700343 }
344
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800345 void expectAlpha(const Rect& rect, uint8_t a) {
Alec Mouri4049b532021-10-15 20:59:33 -0700346 auto generator = [=](Point) { return ubyte4(0, 0, 0, a); };
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800347 auto colorCompare = [](const uint8_t* colorA, const uint8_t* colorB) {
348 return colorA[3] == colorB[3];
349 };
Alec Mouri4049b532021-10-15 20:59:33 -0700350 expectBufferColor(rect, generator, colorCompare);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800351 }
352
353 void expectShadowColor(const renderengine::LayerSettings& castingLayer,
Vishnu Naird9e4f462023-10-06 04:05:45 +0000354 const ShadowSettings& shadow, const ubyte4& casterColor,
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800355 const ubyte4& backgroundColor) {
356 const Rect casterRect(castingLayer.geometry.boundaries);
357 Region casterRegion = Region(casterRect);
Vishnu Nair50c0afe2022-07-11 15:04:07 -0700358 const float casterCornerRadius = (castingLayer.geometry.roundedCornersRadius.x +
359 castingLayer.geometry.roundedCornersRadius.y) /
360 2.0;
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800361 if (casterCornerRadius > 0.0f) {
362 // ignore the corners if a corner radius is set
363 Rect cornerRect(casterCornerRadius, casterCornerRadius);
364 casterRegion.subtractSelf(cornerRect.offsetTo(casterRect.left, casterRect.top));
365 casterRegion.subtractSelf(
366 cornerRect.offsetTo(casterRect.right - casterCornerRadius, casterRect.top));
367 casterRegion.subtractSelf(
368 cornerRect.offsetTo(casterRect.left, casterRect.bottom - casterCornerRadius));
369 casterRegion.subtractSelf(cornerRect.offsetTo(casterRect.right - casterCornerRadius,
370 casterRect.bottom - casterCornerRadius));
371 }
372
373 const float shadowInset = shadow.length * -1.0f;
374 const Rect casterWithShadow =
375 Rect(casterRect).inset(shadowInset, shadowInset, shadowInset, shadowInset);
376 const Region shadowRegion = Region(casterWithShadow).subtractSelf(casterRect);
377 const Region backgroundRegion = Region(fullscreenRect()).subtractSelf(casterWithShadow);
378
379 // verify casting layer
380 expectBufferColor(casterRegion, casterColor.r, casterColor.g, casterColor.b, casterColor.a);
381
382 // verify shadows by testing just the alpha since its difficult to validate the shadow color
383 size_t c;
384 Rect const* r = shadowRegion.getArray(&c);
385 for (size_t i = 0; i < c; i++, r++) {
386 expectAlpha(*r, 255);
387 }
388
389 // verify background
390 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
391 backgroundColor.a);
392 }
393
Vishnu Naird9e4f462023-10-06 04:05:45 +0000394 void expectShadowColorWithoutCaster(const FloatRect& casterBounds, const ShadowSettings& shadow,
Alec Mouribd17b3b2020-12-17 11:08:30 -0800395 const ubyte4& backgroundColor) {
396 const float shadowInset = shadow.length * -1.0f;
397 const Rect casterRect(casterBounds);
398 const Rect shadowRect =
399 Rect(casterRect).inset(shadowInset, shadowInset, shadowInset, shadowInset);
400
401 const Region backgroundRegion =
402 Region(fullscreenRect()).subtractSelf(casterRect).subtractSelf(shadowRect);
403
404 expectAlpha(shadowRect, 255);
405 // (0, 0, 0) fill on the bounds of the layer should be ignored.
406 expectBufferColor(casterRect, 255, 255, 255, 255, 254);
407
408 // verify background
409 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
410 backgroundColor.a);
411 }
412
Vishnu Naird9e4f462023-10-06 04:05:45 +0000413 static ShadowSettings getShadowSettings(const vec2& casterPos, float shadowLength,
414 bool casterIsTranslucent) {
415 ShadowSettings shadow;
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800416 shadow.ambientColor = {0.0f, 0.0f, 0.0f, 0.039f};
417 shadow.spotColor = {0.0f, 0.0f, 0.0f, 0.19f};
418 shadow.lightPos = vec3(casterPos.x, casterPos.y, 0);
419 shadow.lightRadius = 0.0f;
420 shadow.length = shadowLength;
421 shadow.casterIsTranslucent = casterIsTranslucent;
422 return shadow;
423 }
424
Alec Mouri1089aed2018-10-25 21:33:57 -0700425 static Rect fullscreenRect() { return Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT); }
426
427 static Rect offsetRect() {
428 return Rect(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_WIDTH,
429 DEFAULT_DISPLAY_HEIGHT);
430 }
431
432 static Rect offsetRectAtZero() {
433 return Rect(DEFAULT_DISPLAY_WIDTH - DEFAULT_DISPLAY_OFFSET,
434 DEFAULT_DISPLAY_HEIGHT - DEFAULT_DISPLAY_OFFSET);
435 }
436
Sally Qi59a9f502021-10-12 18:53:23 +0000437 void invokeDraw(const renderengine::DisplaySettings& settings,
438 const std::vector<renderengine::LayerSettings>& layers) {
Patrick Williams2e9748f2022-08-09 22:48:18 +0000439 ftl::Future<FenceResult> future =
Alec Mourif29700f2023-08-17 21:53:31 +0000440 mRE->drawLayers(settings, layers, mBuffer, base::unique_fd());
Patrick Williams2e9748f2022-08-09 22:48:18 +0000441 ASSERT_TRUE(future.valid());
Sally Qi59a9f502021-10-12 18:53:23 +0000442
Patrick Williams2e9748f2022-08-09 22:48:18 +0000443 auto result = future.get();
444 ASSERT_TRUE(result.ok());
Alec Mouri1089aed2018-10-25 21:33:57 -0700445
Patrick Williams2e9748f2022-08-09 22:48:18 +0000446 auto fence = result.value();
447 fence->waitForever(LOG_TAG);
Alec Mouri1089aed2018-10-25 21:33:57 -0700448 }
449
Alec Mourid43ccab2019-03-13 12:23:45 -0700450 void drawEmptyLayers() {
Alec Mouri6e57f682018-09-29 20:45:08 -0700451 renderengine::DisplaySettings settings;
Sally Qi59a9f502021-10-12 18:53:23 +0000452 std::vector<renderengine::LayerSettings> layers;
Alec Mouric0aae732021-01-12 13:32:18 -0800453 invokeDraw(settings, layers);
Alec Mouri6e57f682018-09-29 20:45:08 -0700454 }
455
Alec Mouri1089aed2018-10-25 21:33:57 -0700456 template <typename SourceVariant>
457 void fillBuffer(half r, half g, half b, half a);
458
459 template <typename SourceVariant>
460 void fillRedBuffer();
461
462 template <typename SourceVariant>
463 void fillGreenBuffer();
464
465 template <typename SourceVariant>
466 void fillBlueBuffer();
467
468 template <typename SourceVariant>
469 void fillRedTransparentBuffer();
470
471 template <typename SourceVariant>
472 void fillRedOffsetBuffer();
473
474 template <typename SourceVariant>
475 void fillBufferPhysicalOffset();
476
477 template <typename SourceVariant>
Alec Mouri5a6d8572020-03-23 23:56:15 -0700478 void fillBufferCheckers(uint32_t rotation);
Alec Mouri1089aed2018-10-25 21:33:57 -0700479
480 template <typename SourceVariant>
481 void fillBufferCheckersRotate0();
482
483 template <typename SourceVariant>
484 void fillBufferCheckersRotate90();
485
486 template <typename SourceVariant>
487 void fillBufferCheckersRotate180();
488
489 template <typename SourceVariant>
490 void fillBufferCheckersRotate270();
491
492 template <typename SourceVariant>
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800493 void fillBufferWithLayerTransform();
494
495 template <typename SourceVariant>
Alec Mouri1089aed2018-10-25 21:33:57 -0700496 void fillBufferLayerTransform();
497
498 template <typename SourceVariant>
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800499 void fillBufferWithColorTransform();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800500
501 template <typename SourceVariant>
Alec Mouri1089aed2018-10-25 21:33:57 -0700502 void fillBufferColorTransform();
503
Alec Mouri7c94edb2018-12-03 21:23:26 -0800504 template <typename SourceVariant>
Sally Qi2019fd22021-11-22 10:19:04 -0800505 void fillBufferWithColorTransformAndSourceDataspace(const ui::Dataspace sourceDataspace);
506
507 template <typename SourceVariant>
508 void fillBufferColorTransformAndSourceDataspace();
509
510 template <typename SourceVariant>
511 void fillBufferWithColorTransformAndOutputDataspace(const ui::Dataspace outputDataspace);
512
513 template <typename SourceVariant>
514 void fillBufferColorTransformAndOutputDataspace();
515
516 template <typename SourceVariant>
KaiChieh Chuangda2845c2020-12-14 16:49:38 +0800517 void fillBufferWithColorTransformZeroLayerAlpha();
518
519 template <typename SourceVariant>
520 void fillBufferColorTransformZeroLayerAlpha();
521
522 template <typename SourceVariant>
Alec Mouri7c94edb2018-12-03 21:23:26 -0800523 void fillRedBufferWithRoundedCorners();
524
525 template <typename SourceVariant>
526 void fillBufferWithRoundedCorners();
527
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000528 template <typename SourceVariant>
Lucas Dupin19c8f0e2019-11-25 17:55:44 -0800529 void fillBufferAndBlurBackground();
530
531 template <typename SourceVariant>
Alec Mourie8489fd2021-04-29 16:08:56 -0700532 void fillSmallLayerAndBlurBackground();
533
534 template <typename SourceVariant>
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000535 void overlayCorners();
536
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800537 void fillRedBufferTextureTransform();
538
539 void fillBufferTextureTransform();
540
541 void fillRedBufferWithPremultiplyAlpha();
542
543 void fillBufferWithPremultiplyAlpha();
544
545 void fillRedBufferWithoutPremultiplyAlpha();
546
547 void fillBufferWithoutPremultiplyAlpha();
548
Alec Mouriac335532018-11-12 15:01:33 -0800549 void fillGreenColorBufferThenClearRegion();
550
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800551 template <typename SourceVariant>
Vishnu Naird9e4f462023-10-06 04:05:45 +0000552 void drawShadow(const renderengine::LayerSettings& castingLayer, const ShadowSettings& shadow,
553 const ubyte4& casterColor, const ubyte4& backgroundColor);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800554
Vishnu Naird9e4f462023-10-06 04:05:45 +0000555 void drawShadowWithoutCaster(const FloatRect& castingBounds, const ShadowSettings& shadow,
Alec Mouribd17b3b2020-12-17 11:08:30 -0800556 const ubyte4& backgroundColor);
557
Alec Mouri5a493722022-01-26 16:43:02 -0800558 // Tonemaps grey values from sourceDataspace -> Display P3 and checks that GPU and CPU
559 // implementations are identical Also implicitly checks that the injected tonemap shader
560 // compiles
561 void tonemap(ui::Dataspace sourceDataspace, std::function<vec3(vec3)> eotf,
562 std::function<vec3(vec3, float)> scaleOotf);
563
Alec Mouric0aae732021-01-12 13:32:18 -0800564 void initializeRenderEngine();
565
566 std::unique_ptr<renderengine::RenderEngine> mRE;
Alec Mouria90a5702021-04-16 16:36:21 +0000567 std::shared_ptr<renderengine::ExternalTexture> mBuffer;
Alec Mouri6e57f682018-09-29 20:45:08 -0700568};
569
Alec Mouric0aae732021-01-12 13:32:18 -0800570void RenderEngineTest::initializeRenderEngine() {
571 const auto& renderEngineFactory = GetParam();
Alec Mouric16974e2022-09-13 17:35:48 +0000572 mRE = renderEngineFactory->createRenderEngine();
Alec Mouria90a5702021-04-16 16:36:21 +0000573 mBuffer = allocateDefaultBuffer();
Alec Mouric0aae732021-01-12 13:32:18 -0800574}
575
Alec Mouri1089aed2018-10-25 21:33:57 -0700576struct ColorSourceVariant {
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800577 static void fillColor(renderengine::LayerSettings& layer, half r, half g, half b,
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800578 RenderEngineTest* /*fixture*/) {
Alec Mouri1089aed2018-10-25 21:33:57 -0700579 layer.source.solidColor = half3(r, g, b);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800580 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700581 }
582};
583
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800584struct RelaxOpaqueBufferVariant {
585 static void setOpaqueBit(renderengine::LayerSettings& layer) {
586 layer.source.buffer.isOpaque = false;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800587 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800588 }
589
590 static uint8_t getAlphaChannel() { return 255; }
591};
592
593struct ForceOpaqueBufferVariant {
594 static void setOpaqueBit(renderengine::LayerSettings& layer) {
595 layer.source.buffer.isOpaque = true;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800596 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800597 }
598
599 static uint8_t getAlphaChannel() {
600 // The isOpaque bit will override the alpha channel, so this should be
601 // arbitrary.
Alec Mouric0aae732021-01-12 13:32:18 -0800602 return 50;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800603 }
604};
605
606template <typename OpaquenessVariant>
607struct BufferSourceVariant {
608 static void fillColor(renderengine::LayerSettings& layer, half r, half g, half b,
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800609 RenderEngineTest* fixture) {
Alec Mouria90a5702021-04-16 16:36:21 +0000610 const auto buf = fixture->allocateSourceBuffer(1, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800611
612 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +0000613 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
614 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800615
Alec Mouria90a5702021-04-16 16:36:21 +0000616 for (int32_t j = 0; j < buf->getBuffer()->getHeight(); j++) {
617 uint8_t* iter = pixels + (buf->getBuffer()->getStride() * j) * 4;
618 for (int32_t i = 0; i < buf->getBuffer()->getWidth(); i++) {
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800619 iter[0] = uint8_t(r * 255);
620 iter[1] = uint8_t(g * 255);
621 iter[2] = uint8_t(b * 255);
622 iter[3] = OpaquenessVariant::getAlphaChannel();
623 iter += 4;
624 }
625 }
626
Alec Mouria90a5702021-04-16 16:36:21 +0000627 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800628
629 layer.source.buffer.buffer = buf;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800630 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800631 OpaquenessVariant::setOpaqueBit(layer);
632 }
633};
634
Alec Mouri1089aed2018-10-25 21:33:57 -0700635template <typename SourceVariant>
636void RenderEngineTest::fillBuffer(half r, half g, half b, half a) {
637 renderengine::DisplaySettings settings;
638 settings.physicalDisplay = fullscreenRect();
639 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800640 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700641
Sally Qi59a9f502021-10-12 18:53:23 +0000642 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700643
644 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800645 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700646 layer.geometry.boundaries = fullscreenRect().toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800647 SourceVariant::fillColor(layer, r, g, b, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700648 layer.alpha = a;
649
Sally Qi59a9f502021-10-12 18:53:23 +0000650 layers.push_back(layer);
Alec Mouri1089aed2018-10-25 21:33:57 -0700651
Alec Mouric0aae732021-01-12 13:32:18 -0800652 invokeDraw(settings, layers);
Alec Mouri1089aed2018-10-25 21:33:57 -0700653}
654
655template <typename SourceVariant>
656void RenderEngineTest::fillRedBuffer() {
657 fillBuffer<SourceVariant>(1.0f, 0.0f, 0.0f, 1.0f);
658 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
659}
660
661template <typename SourceVariant>
662void RenderEngineTest::fillGreenBuffer() {
663 fillBuffer<SourceVariant>(0.0f, 1.0f, 0.0f, 1.0f);
664 expectBufferColor(fullscreenRect(), 0, 255, 0, 255);
665}
666
667template <typename SourceVariant>
668void RenderEngineTest::fillBlueBuffer() {
669 fillBuffer<SourceVariant>(0.0f, 0.0f, 1.0f, 1.0f);
670 expectBufferColor(fullscreenRect(), 0, 0, 255, 255);
671}
672
673template <typename SourceVariant>
674void RenderEngineTest::fillRedTransparentBuffer() {
675 fillBuffer<SourceVariant>(1.0f, 0.0f, 0.0f, .2f);
676 expectBufferColor(fullscreenRect(), 51, 0, 0, 51);
677}
678
679template <typename SourceVariant>
680void RenderEngineTest::fillRedOffsetBuffer() {
681 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800682 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700683 settings.physicalDisplay = offsetRect();
684 settings.clip = offsetRectAtZero();
685
Sally Qi59a9f502021-10-12 18:53:23 +0000686 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700687
688 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800689 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700690 layer.geometry.boundaries = offsetRectAtZero().toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800691 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700692 layer.alpha = 1.0f;
693
Sally Qi59a9f502021-10-12 18:53:23 +0000694 layers.push_back(layer);
Alec Mouric0aae732021-01-12 13:32:18 -0800695 invokeDraw(settings, layers);
Alec Mouri1089aed2018-10-25 21:33:57 -0700696}
697
698template <typename SourceVariant>
699void RenderEngineTest::fillBufferPhysicalOffset() {
700 fillRedOffsetBuffer<SourceVariant>();
701
702 expectBufferColor(Rect(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_WIDTH,
703 DEFAULT_DISPLAY_HEIGHT),
704 255, 0, 0, 255);
705 Rect offsetRegionLeft(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_HEIGHT);
706 Rect offsetRegionTop(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_OFFSET);
707
708 expectBufferColor(offsetRegionLeft, 0, 0, 0, 0);
709 expectBufferColor(offsetRegionTop, 0, 0, 0, 0);
710}
711
712template <typename SourceVariant>
Alec Mouri5a6d8572020-03-23 23:56:15 -0700713void RenderEngineTest::fillBufferCheckers(uint32_t orientationFlag) {
Alec Mouri1089aed2018-10-25 21:33:57 -0700714 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800715 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700716 settings.physicalDisplay = fullscreenRect();
717 // Here logical space is 2x2
718 settings.clip = Rect(2, 2);
Alec Mouri5a6d8572020-03-23 23:56:15 -0700719 settings.orientation = orientationFlag;
Alec Mouri1089aed2018-10-25 21:33:57 -0700720
Sally Qi59a9f502021-10-12 18:53:23 +0000721 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700722
723 renderengine::LayerSettings layerOne;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800724 layerOne.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700725 Rect rectOne(0, 0, 1, 1);
726 layerOne.geometry.boundaries = rectOne.toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800727 SourceVariant::fillColor(layerOne, 1.0f, 0.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700728 layerOne.alpha = 1.0f;
729
730 renderengine::LayerSettings layerTwo;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800731 layerTwo.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700732 Rect rectTwo(0, 1, 1, 2);
733 layerTwo.geometry.boundaries = rectTwo.toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800734 SourceVariant::fillColor(layerTwo, 0.0f, 1.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700735 layerTwo.alpha = 1.0f;
736
737 renderengine::LayerSettings layerThree;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800738 layerThree.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700739 Rect rectThree(1, 0, 2, 1);
740 layerThree.geometry.boundaries = rectThree.toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800741 SourceVariant::fillColor(layerThree, 0.0f, 0.0f, 1.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700742 layerThree.alpha = 1.0f;
743
Sally Qi59a9f502021-10-12 18:53:23 +0000744 layers.push_back(layerOne);
745 layers.push_back(layerTwo);
746 layers.push_back(layerThree);
Alec Mouri1089aed2018-10-25 21:33:57 -0700747
Alec Mouric0aae732021-01-12 13:32:18 -0800748 invokeDraw(settings, layers);
Alec Mouri1089aed2018-10-25 21:33:57 -0700749}
750
751template <typename SourceVariant>
752void RenderEngineTest::fillBufferCheckersRotate0() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700753 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_0);
Alec Mouri1089aed2018-10-25 21:33:57 -0700754 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0,
755 255);
756 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
757 DEFAULT_DISPLAY_HEIGHT / 2),
758 0, 0, 255, 255);
759 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
760 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
761 0, 0, 0, 0);
762 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
763 DEFAULT_DISPLAY_HEIGHT),
764 0, 255, 0, 255);
765}
766
767template <typename SourceVariant>
768void RenderEngineTest::fillBufferCheckersRotate90() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700769 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_90);
Alec Mouri1089aed2018-10-25 21:33:57 -0700770 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 255, 0,
771 255);
772 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
773 DEFAULT_DISPLAY_HEIGHT / 2),
774 255, 0, 0, 255);
775 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
776 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
777 0, 0, 255, 255);
778 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
779 DEFAULT_DISPLAY_HEIGHT),
780 0, 0, 0, 0);
781}
782
783template <typename SourceVariant>
784void RenderEngineTest::fillBufferCheckersRotate180() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700785 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_180);
Alec Mouri1089aed2018-10-25 21:33:57 -0700786 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 0,
787 0);
788 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
789 DEFAULT_DISPLAY_HEIGHT / 2),
790 0, 255, 0, 255);
791 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
792 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
793 255, 0, 0, 255);
794 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
795 DEFAULT_DISPLAY_HEIGHT),
796 0, 0, 255, 255);
797}
798
799template <typename SourceVariant>
800void RenderEngineTest::fillBufferCheckersRotate270() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700801 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_270);
Alec Mouri1089aed2018-10-25 21:33:57 -0700802 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 255,
803 255);
804 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
805 DEFAULT_DISPLAY_HEIGHT / 2),
806 0, 0, 0, 0);
807 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
808 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
809 0, 255, 0, 255);
810 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
811 DEFAULT_DISPLAY_HEIGHT),
812 255, 0, 0, 255);
813}
814
815template <typename SourceVariant>
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800816void RenderEngineTest::fillBufferWithLayerTransform() {
Alec Mouri1089aed2018-10-25 21:33:57 -0700817 renderengine::DisplaySettings settings;
818 settings.physicalDisplay = fullscreenRect();
819 // Here logical space is 2x2
820 settings.clip = Rect(2, 2);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800821 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700822
Sally Qi59a9f502021-10-12 18:53:23 +0000823 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700824
825 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800826 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700827 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
828 // Translate one pixel diagonally
829 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 -0800830 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700831 layer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
832 layer.alpha = 1.0f;
833
Sally Qi59a9f502021-10-12 18:53:23 +0000834 layers.push_back(layer);
Alec Mouri1089aed2018-10-25 21:33:57 -0700835
Alec Mouric0aae732021-01-12 13:32:18 -0800836 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800837}
Alec Mouri1089aed2018-10-25 21:33:57 -0700838
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800839template <typename SourceVariant>
840void RenderEngineTest::fillBufferLayerTransform() {
841 fillBufferWithLayerTransform<SourceVariant>();
Alec Mouri1089aed2018-10-25 21:33:57 -0700842 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 0, 0);
843 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
844 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
845 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
846 255, 0, 0, 255);
847}
848
849template <typename SourceVariant>
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800850void RenderEngineTest::fillBufferWithColorTransform() {
Alec Mouri1089aed2018-10-25 21:33:57 -0700851 renderengine::DisplaySettings settings;
852 settings.physicalDisplay = fullscreenRect();
853 settings.clip = Rect(1, 1);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800854 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700855
Sally Qi59a9f502021-10-12 18:53:23 +0000856 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700857
858 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800859 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700860 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800861 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700862 layer.alpha = 1.0f;
863
864 // construct a fake color matrix
865 // annihilate green and blue channels
KaiChieh Chuang436fc192020-09-07 13:48:42 +0800866 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
Alec Mouri1089aed2018-10-25 21:33:57 -0700867 // set red channel to red + green
868 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
869
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800870 layer.alpha = 1.0f;
871 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
872
Sally Qi59a9f502021-10-12 18:53:23 +0000873 layers.push_back(layer);
Alec Mouri1089aed2018-10-25 21:33:57 -0700874
Alec Mouric0aae732021-01-12 13:32:18 -0800875 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800876}
Alec Mouri1089aed2018-10-25 21:33:57 -0700877
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800878template <typename SourceVariant>
Sally Qi2019fd22021-11-22 10:19:04 -0800879void RenderEngineTest::fillBufferWithColorTransformAndSourceDataspace(
880 const ui::Dataspace sourceDataspace) {
881 renderengine::DisplaySettings settings;
882 settings.physicalDisplay = fullscreenRect();
883 settings.clip = Rect(1, 1);
884 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
885
886 std::vector<renderengine::LayerSettings> layers;
887
888 renderengine::LayerSettings layer;
Sally Qi2019fd22021-11-22 10:19:04 -0800889 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
890 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
Alec Mouric16974e2022-09-13 17:35:48 +0000891 layer.sourceDataspace = sourceDataspace;
Sally Qi2019fd22021-11-22 10:19:04 -0800892 layer.alpha = 1.0f;
893
894 // construct a fake color matrix
895 // annihilate green and blue channels
896 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
897 // set red channel to red + green
898 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
899
900 layer.alpha = 1.0f;
901 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
902
903 layers.push_back(layer);
904
905 invokeDraw(settings, layers);
906}
907
908template <typename SourceVariant>
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800909void RenderEngineTest::fillBufferColorTransform() {
910 fillBufferWithColorTransform<SourceVariant>();
KaiChieh Chuang436fc192020-09-07 13:48:42 +0800911 expectBufferColor(fullscreenRect(), 172, 0, 0, 255, 1);
912}
913
914template <typename SourceVariant>
Sally Qi2019fd22021-11-22 10:19:04 -0800915void RenderEngineTest::fillBufferColorTransformAndSourceDataspace() {
916 unordered_map<ui::Dataspace, ubyte4> dataspaceToColorMap;
Alec Mouric16974e2022-09-13 17:35:48 +0000917 dataspaceToColorMap[ui::Dataspace::V0_BT709] = {77, 0, 0, 255};
918 dataspaceToColorMap[ui::Dataspace::BT2020] = {101, 0, 0, 255};
919 dataspaceToColorMap[ui::Dataspace::ADOBE_RGB] = {75, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -0800920 ui::Dataspace customizedDataspace = static_cast<ui::Dataspace>(
921 ui::Dataspace::STANDARD_BT709 | ui::Dataspace::TRANSFER_GAMMA2_2 |
922 ui::Dataspace::RANGE_FULL);
Alec Mouric16974e2022-09-13 17:35:48 +0000923 dataspaceToColorMap[customizedDataspace] = {61, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -0800924 for (const auto& [sourceDataspace, color] : dataspaceToColorMap) {
925 fillBufferWithColorTransformAndSourceDataspace<SourceVariant>(sourceDataspace);
926 expectBufferColor(fullscreenRect(), color.r, color.g, color.b, color.a, 1);
927 }
928}
929
930template <typename SourceVariant>
931void RenderEngineTest::fillBufferWithColorTransformAndOutputDataspace(
932 const ui::Dataspace outputDataspace) {
933 renderengine::DisplaySettings settings;
934 settings.physicalDisplay = fullscreenRect();
935 settings.clip = Rect(1, 1);
936 settings.outputDataspace = outputDataspace;
937
938 std::vector<renderengine::LayerSettings> layers;
939
940 renderengine::LayerSettings layer;
941 layer.sourceDataspace = ui::Dataspace::V0_SCRGB_LINEAR;
942 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
943 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
944 layer.alpha = 1.0f;
945
946 // construct a fake color matrix
947 // annihilate green and blue channels
948 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
949 // set red channel to red + green
950 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
951
952 layer.alpha = 1.0f;
953 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
954
955 layers.push_back(layer);
956
957 invokeDraw(settings, layers);
958}
959
960template <typename SourceVariant>
961void RenderEngineTest::fillBufferColorTransformAndOutputDataspace() {
962 unordered_map<ui::Dataspace, ubyte4> dataspaceToColorMap;
Alec Mouric16974e2022-09-13 17:35:48 +0000963 dataspaceToColorMap[ui::Dataspace::V0_BT709] = {198, 0, 0, 255};
964 dataspaceToColorMap[ui::Dataspace::BT2020] = {187, 0, 0, 255};
965 dataspaceToColorMap[ui::Dataspace::ADOBE_RGB] = {192, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -0800966 ui::Dataspace customizedDataspace = static_cast<ui::Dataspace>(
967 ui::Dataspace::STANDARD_BT709 | ui::Dataspace::TRANSFER_GAMMA2_6 |
968 ui::Dataspace::RANGE_FULL);
Alec Mouric16974e2022-09-13 17:35:48 +0000969 dataspaceToColorMap[customizedDataspace] = {205, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -0800970 for (const auto& [outputDataspace, color] : dataspaceToColorMap) {
971 fillBufferWithColorTransformAndOutputDataspace<SourceVariant>(outputDataspace);
972 expectBufferColor(fullscreenRect(), color.r, color.g, color.b, color.a, 1);
973 }
974}
975
976template <typename SourceVariant>
KaiChieh Chuangda2845c2020-12-14 16:49:38 +0800977void RenderEngineTest::fillBufferWithColorTransformZeroLayerAlpha() {
978 renderengine::DisplaySettings settings;
979 settings.physicalDisplay = fullscreenRect();
980 settings.clip = Rect(1, 1);
981
Sally Qi59a9f502021-10-12 18:53:23 +0000982 std::vector<renderengine::LayerSettings> layers;
KaiChieh Chuangda2845c2020-12-14 16:49:38 +0800983
984 renderengine::LayerSettings layer;
985 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
986 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
987 layer.alpha = 0;
988
989 // construct a fake color matrix
990 // simple inverse color
991 settings.colorTransform = mat4(-1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 1, 1, 1, 1);
992
993 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
994
Sally Qi59a9f502021-10-12 18:53:23 +0000995 layers.push_back(layer);
KaiChieh Chuangda2845c2020-12-14 16:49:38 +0800996
Alec Mouric0aae732021-01-12 13:32:18 -0800997 invokeDraw(settings, layers);
KaiChieh Chuangda2845c2020-12-14 16:49:38 +0800998}
999
1000template <typename SourceVariant>
1001void RenderEngineTest::fillBufferColorTransformZeroLayerAlpha() {
1002 fillBufferWithColorTransformZeroLayerAlpha<SourceVariant>();
1003 expectBufferColor(fullscreenRect(), 0, 0, 0, 0);
1004}
1005
1006template <typename SourceVariant>
Alec Mouri7c94edb2018-12-03 21:23:26 -08001007void RenderEngineTest::fillRedBufferWithRoundedCorners() {
1008 renderengine::DisplaySettings settings;
1009 settings.physicalDisplay = fullscreenRect();
1010 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001011 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri7c94edb2018-12-03 21:23:26 -08001012
Sally Qi59a9f502021-10-12 18:53:23 +00001013 std::vector<renderengine::LayerSettings> layers;
Alec Mouri7c94edb2018-12-03 21:23:26 -08001014
1015 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001016 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri7c94edb2018-12-03 21:23:26 -08001017 layer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07001018 layer.geometry.roundedCornersRadius = {5.0f, 5.0f};
Alec Mouri7c94edb2018-12-03 21:23:26 -08001019 layer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
1020 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
1021 layer.alpha = 1.0f;
1022
Sally Qi59a9f502021-10-12 18:53:23 +00001023 layers.push_back(layer);
Alec Mouri7c94edb2018-12-03 21:23:26 -08001024
Alec Mouric0aae732021-01-12 13:32:18 -08001025 invokeDraw(settings, layers);
Alec Mouri7c94edb2018-12-03 21:23:26 -08001026}
1027
1028template <typename SourceVariant>
1029void RenderEngineTest::fillBufferWithRoundedCorners() {
1030 fillRedBufferWithRoundedCorners<SourceVariant>();
1031 // Corners should be ignored...
1032 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 0);
1033 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, 0, DEFAULT_DISPLAY_WIDTH, 1), 0, 0, 0, 0);
1034 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT - 1, 1, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
1035 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1,
1036 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1037 0, 0, 0, 0);
1038 // ...And the non-rounded portion should be red.
1039 // Other pixels may be anti-aliased, so let's not check those.
1040 expectBufferColor(Rect(5, 5, DEFAULT_DISPLAY_WIDTH - 5, DEFAULT_DISPLAY_HEIGHT - 5), 255, 0, 0,
1041 255);
1042}
1043
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001044template <typename SourceVariant>
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001045void RenderEngineTest::fillBufferAndBlurBackground() {
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001046 auto blurRadius = 50;
1047 auto center = DEFAULT_DISPLAY_WIDTH / 2;
1048
1049 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001050 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001051 settings.physicalDisplay = fullscreenRect();
1052 settings.clip = fullscreenRect();
1053
Sally Qi59a9f502021-10-12 18:53:23 +00001054 std::vector<renderengine::LayerSettings> layers;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001055
1056 renderengine::LayerSettings backgroundLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001057 backgroundLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001058 backgroundLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1059 SourceVariant::fillColor(backgroundLayer, 0.0f, 1.0f, 0.0f, this);
1060 backgroundLayer.alpha = 1.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001061 layers.emplace_back(backgroundLayer);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001062
1063 renderengine::LayerSettings leftLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001064 leftLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001065 leftLayer.geometry.boundaries =
1066 Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT).toFloatRect();
1067 SourceVariant::fillColor(leftLayer, 1.0f, 0.0f, 0.0f, this);
1068 leftLayer.alpha = 1.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001069 layers.emplace_back(leftLayer);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001070
1071 renderengine::LayerSettings blurLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001072 blurLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001073 blurLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1074 blurLayer.backgroundBlurRadius = blurRadius;
Derek Sollenbergerecb21462021-01-29 16:53:49 -05001075 SourceVariant::fillColor(blurLayer, 0.0f, 0.0f, 1.0f, this);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001076 blurLayer.alpha = 0;
Sally Qi59a9f502021-10-12 18:53:23 +00001077 layers.emplace_back(blurLayer);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001078
Alec Mouric0aae732021-01-12 13:32:18 -08001079 invokeDraw(settings, layers);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001080
Derek Sollenbergerecb21462021-01-29 16:53:49 -05001081 // solid color
1082 expectBufferColor(Rect(0, 0, 1, 1), 255, 0, 0, 255, 0 /* tolerance */);
1083
Derek Sollenbergerb3998372021-02-16 15:16:56 -05001084 if (mRE->supportsBackgroundBlur()) {
1085 // blurred color (downsampling should result in the center color being close to 128)
1086 expectBufferColor(Rect(center - 1, center - 5, center + 1, center + 5), 128, 128, 0, 255,
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001087 50 /* tolerance */);
Derek Sollenbergerb3998372021-02-16 15:16:56 -05001088 }
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001089}
1090
1091template <typename SourceVariant>
Alec Mourie8489fd2021-04-29 16:08:56 -07001092void RenderEngineTest::fillSmallLayerAndBlurBackground() {
1093 auto blurRadius = 50;
1094 renderengine::DisplaySettings settings;
1095 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1096 settings.physicalDisplay = fullscreenRect();
1097 settings.clip = fullscreenRect();
1098
Sally Qi59a9f502021-10-12 18:53:23 +00001099 std::vector<renderengine::LayerSettings> layers;
Alec Mourie8489fd2021-04-29 16:08:56 -07001100
1101 renderengine::LayerSettings backgroundLayer;
1102 backgroundLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1103 backgroundLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1104 SourceVariant::fillColor(backgroundLayer, 1.0f, 0.0f, 0.0f, this);
1105 backgroundLayer.alpha = 1.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001106 layers.push_back(backgroundLayer);
Alec Mourie8489fd2021-04-29 16:08:56 -07001107
1108 renderengine::LayerSettings blurLayer;
1109 blurLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1110 blurLayer.geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f);
1111 blurLayer.backgroundBlurRadius = blurRadius;
1112 SourceVariant::fillColor(blurLayer, 0.0f, 0.0f, 1.0f, this);
1113 blurLayer.alpha = 0;
Sally Qi59a9f502021-10-12 18:53:23 +00001114 layers.push_back(blurLayer);
Alec Mourie8489fd2021-04-29 16:08:56 -07001115
1116 invokeDraw(settings, layers);
1117
1118 // Give a generous tolerance - the blur rectangle is very small and this test is
1119 // mainly concerned with ensuring that there's no device failure.
1120 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT), 255, 0, 0, 255,
1121 40 /* tolerance */);
1122}
1123
1124template <typename SourceVariant>
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001125void RenderEngineTest::overlayCorners() {
1126 renderengine::DisplaySettings settings;
1127 settings.physicalDisplay = fullscreenRect();
1128 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001129 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001130
Sally Qi59a9f502021-10-12 18:53:23 +00001131 std::vector<renderengine::LayerSettings> layersFirst;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001132
1133 renderengine::LayerSettings layerOne;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001134 layerOne.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001135 layerOne.geometry.boundaries =
1136 FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH / 3.0, DEFAULT_DISPLAY_HEIGHT / 3.0);
1137 SourceVariant::fillColor(layerOne, 1.0f, 0.0f, 0.0f, this);
1138 layerOne.alpha = 0.2;
1139
Sally Qi59a9f502021-10-12 18:53:23 +00001140 layersFirst.push_back(layerOne);
Alec Mouric0aae732021-01-12 13:32:18 -08001141 invokeDraw(settings, layersFirst);
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001142 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3), 51, 0, 0, 51);
1143 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3 + 1, DEFAULT_DISPLAY_HEIGHT / 3 + 1,
1144 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1145 0, 0, 0, 0);
1146
Sally Qi59a9f502021-10-12 18:53:23 +00001147 std::vector<renderengine::LayerSettings> layersSecond;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001148 renderengine::LayerSettings layerTwo;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001149 layerTwo.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001150 layerTwo.geometry.boundaries =
1151 FloatRect(DEFAULT_DISPLAY_WIDTH / 3.0, DEFAULT_DISPLAY_HEIGHT / 3.0,
1152 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT);
1153 SourceVariant::fillColor(layerTwo, 0.0f, 1.0f, 0.0f, this);
1154 layerTwo.alpha = 1.0f;
1155
Sally Qi59a9f502021-10-12 18:53:23 +00001156 layersSecond.push_back(layerTwo);
Alec Mouric0aae732021-01-12 13:32:18 -08001157 invokeDraw(settings, layersSecond);
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001158
1159 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3), 0, 0, 0, 0);
1160 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3 + 1, DEFAULT_DISPLAY_HEIGHT / 3 + 1,
1161 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1162 0, 255, 0, 255);
1163}
1164
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001165void RenderEngineTest::fillRedBufferTextureTransform() {
1166 renderengine::DisplaySettings settings;
1167 settings.physicalDisplay = fullscreenRect();
1168 settings.clip = Rect(1, 1);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001169 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001170
Sally Qi59a9f502021-10-12 18:53:23 +00001171 std::vector<renderengine::LayerSettings> layers;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001172
1173 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001174 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001175 // Here will allocate a checker board texture, but transform texture
1176 // coordinates so that only the upper left is applied.
Alec Mouria90a5702021-04-16 16:36:21 +00001177 const auto buf = allocateSourceBuffer(2, 2);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001178
1179 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00001180 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1181 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001182 // Red top left, Green top right, Blue bottom left, Black bottom right
1183 pixels[0] = 255;
1184 pixels[1] = 0;
1185 pixels[2] = 0;
1186 pixels[3] = 255;
1187 pixels[4] = 0;
1188 pixels[5] = 255;
1189 pixels[6] = 0;
1190 pixels[7] = 255;
1191 pixels[8] = 0;
1192 pixels[9] = 0;
1193 pixels[10] = 255;
1194 pixels[11] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00001195 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001196
1197 layer.source.buffer.buffer = buf;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001198 // Transform coordinates to only be inside the red quadrant.
Alec Mouri4049b532021-10-15 20:59:33 -07001199 layer.source.buffer.textureTransform = mat4::scale(vec4(0.2f, 0.2f, 1.f, 1.f));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001200 layer.alpha = 1.0f;
1201 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1202
Sally Qi59a9f502021-10-12 18:53:23 +00001203 layers.push_back(layer);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001204
Alec Mouric0aae732021-01-12 13:32:18 -08001205 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001206}
1207
1208void RenderEngineTest::fillBufferTextureTransform() {
1209 fillRedBufferTextureTransform();
1210 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
1211}
1212
1213void RenderEngineTest::fillRedBufferWithPremultiplyAlpha() {
1214 renderengine::DisplaySettings settings;
1215 settings.physicalDisplay = fullscreenRect();
1216 // Here logical space is 1x1
1217 settings.clip = Rect(1, 1);
1218
Sally Qi59a9f502021-10-12 18:53:23 +00001219 std::vector<renderengine::LayerSettings> layers;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001220
1221 renderengine::LayerSettings layer;
Alec Mouria90a5702021-04-16 16:36:21 +00001222 const auto buf = allocateSourceBuffer(1, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001223
1224 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00001225 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1226 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001227 pixels[0] = 255;
1228 pixels[1] = 0;
1229 pixels[2] = 0;
1230 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00001231 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001232
1233 layer.source.buffer.buffer = buf;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001234 layer.source.buffer.usePremultipliedAlpha = true;
1235 layer.alpha = 0.5f;
1236 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1237
Sally Qi59a9f502021-10-12 18:53:23 +00001238 layers.push_back(layer);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001239
Alec Mouric0aae732021-01-12 13:32:18 -08001240 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001241}
1242
1243void RenderEngineTest::fillBufferWithPremultiplyAlpha() {
1244 fillRedBufferWithPremultiplyAlpha();
1245 expectBufferColor(fullscreenRect(), 128, 0, 0, 128);
1246}
1247
1248void RenderEngineTest::fillRedBufferWithoutPremultiplyAlpha() {
1249 renderengine::DisplaySettings settings;
1250 settings.physicalDisplay = fullscreenRect();
1251 // Here logical space is 1x1
1252 settings.clip = Rect(1, 1);
1253
Sally Qi59a9f502021-10-12 18:53:23 +00001254 std::vector<renderengine::LayerSettings> layers;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001255
1256 renderengine::LayerSettings layer;
Alec Mouria90a5702021-04-16 16:36:21 +00001257 const auto buf = allocateSourceBuffer(1, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001258
1259 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00001260 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1261 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001262 pixels[0] = 255;
1263 pixels[1] = 0;
1264 pixels[2] = 0;
1265 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00001266 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001267
1268 layer.source.buffer.buffer = buf;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001269 layer.source.buffer.usePremultipliedAlpha = false;
1270 layer.alpha = 0.5f;
1271 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1272
Sally Qi59a9f502021-10-12 18:53:23 +00001273 layers.push_back(layer);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001274
Alec Mouric0aae732021-01-12 13:32:18 -08001275 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001276}
1277
1278void RenderEngineTest::fillBufferWithoutPremultiplyAlpha() {
1279 fillRedBufferWithoutPremultiplyAlpha();
wukui16f3c0bb2020-08-05 20:35:29 +08001280 expectBufferColor(fullscreenRect(), 128, 0, 0, 128, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001281}
1282
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001283template <typename SourceVariant>
1284void RenderEngineTest::drawShadow(const renderengine::LayerSettings& castingLayer,
Vishnu Naird9e4f462023-10-06 04:05:45 +00001285 const ShadowSettings& shadow, const ubyte4& casterColor,
1286 const ubyte4& backgroundColor) {
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001287 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001288 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001289 settings.physicalDisplay = fullscreenRect();
1290 settings.clip = fullscreenRect();
1291
Sally Qi59a9f502021-10-12 18:53:23 +00001292 std::vector<renderengine::LayerSettings> layers;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001293
1294 // add background layer
1295 renderengine::LayerSettings bgLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001296 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001297 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1298 ColorSourceVariant::fillColor(bgLayer, backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1299 backgroundColor.b / 255.0f, this);
1300 bgLayer.alpha = backgroundColor.a / 255.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001301 layers.push_back(bgLayer);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001302
1303 // add shadow layer
1304 renderengine::LayerSettings shadowLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001305 shadowLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001306 shadowLayer.geometry.boundaries = castingLayer.geometry.boundaries;
1307 shadowLayer.alpha = castingLayer.alpha;
1308 shadowLayer.shadow = shadow;
Sally Qi59a9f502021-10-12 18:53:23 +00001309 layers.push_back(shadowLayer);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001310
1311 // add layer casting the shadow
1312 renderengine::LayerSettings layer = castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001313 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001314 SourceVariant::fillColor(layer, casterColor.r / 255.0f, casterColor.g / 255.0f,
1315 casterColor.b / 255.0f, this);
Sally Qi59a9f502021-10-12 18:53:23 +00001316 layers.push_back(layer);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001317
Alec Mouric0aae732021-01-12 13:32:18 -08001318 invokeDraw(settings, layers);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001319}
1320
Alec Mouribd17b3b2020-12-17 11:08:30 -08001321void RenderEngineTest::drawShadowWithoutCaster(const FloatRect& castingBounds,
Vishnu Naird9e4f462023-10-06 04:05:45 +00001322 const ShadowSettings& shadow,
Alec Mouribd17b3b2020-12-17 11:08:30 -08001323 const ubyte4& backgroundColor) {
1324 renderengine::DisplaySettings settings;
1325 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1326 settings.physicalDisplay = fullscreenRect();
1327 settings.clip = fullscreenRect();
1328
Sally Qi59a9f502021-10-12 18:53:23 +00001329 std::vector<renderengine::LayerSettings> layers;
Alec Mouribd17b3b2020-12-17 11:08:30 -08001330
1331 // add background layer
1332 renderengine::LayerSettings bgLayer;
1333 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1334 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1335 ColorSourceVariant::fillColor(bgLayer, backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1336 backgroundColor.b / 255.0f, this);
1337 bgLayer.alpha = backgroundColor.a / 255.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001338 layers.push_back(bgLayer);
Alec Mouribd17b3b2020-12-17 11:08:30 -08001339
1340 // add shadow layer
1341 renderengine::LayerSettings shadowLayer;
1342 shadowLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1343 shadowLayer.geometry.boundaries = castingBounds;
Derek Sollenbergerc31985e2021-05-18 16:38:17 -04001344 shadowLayer.skipContentDraw = true;
Alec Mouribd17b3b2020-12-17 11:08:30 -08001345 shadowLayer.alpha = 1.0f;
1346 ColorSourceVariant::fillColor(shadowLayer, 0, 0, 0, this);
1347 shadowLayer.shadow = shadow;
Sally Qi59a9f502021-10-12 18:53:23 +00001348 layers.push_back(shadowLayer);
Alec Mouribd17b3b2020-12-17 11:08:30 -08001349
Alec Mouric0aae732021-01-12 13:32:18 -08001350 invokeDraw(settings, layers);
Alec Mouribd17b3b2020-12-17 11:08:30 -08001351}
1352
Alec Mouri5a493722022-01-26 16:43:02 -08001353void RenderEngineTest::tonemap(ui::Dataspace sourceDataspace, std::function<vec3(vec3)> eotf,
1354 std::function<vec3(vec3, float)> scaleOotf) {
1355 constexpr int32_t kGreyLevels = 256;
1356
1357 const auto rect = Rect(0, 0, kGreyLevels, 1);
1358
1359 constexpr float kMaxLuminance = 750.f;
1360 constexpr float kCurrentLuminanceNits = 500.f;
1361 const renderengine::DisplaySettings display{
1362 .physicalDisplay = rect,
1363 .clip = rect,
1364 .maxLuminance = kMaxLuminance,
1365 .currentLuminanceNits = kCurrentLuminanceNits,
1366 .outputDataspace = ui::Dataspace::DISPLAY_P3,
1367 };
1368
1369 auto buf = std::make_shared<
1370 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07001371 ExternalTexture>(sp<GraphicBuffer>::make(kGreyLevels, 1,
1372 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1373 GRALLOC_USAGE_SW_READ_OFTEN |
1374 GRALLOC_USAGE_SW_WRITE_OFTEN |
1375 GRALLOC_USAGE_HW_RENDER |
1376 GRALLOC_USAGE_HW_TEXTURE,
1377 "input"),
Alec Mouri5a493722022-01-26 16:43:02 -08001378 *mRE,
1379 renderengine::impl::ExternalTexture::Usage::READABLE |
1380 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
1381 ASSERT_EQ(0, buf->getBuffer()->initCheck());
1382 {
1383 uint8_t* pixels;
1384 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1385 reinterpret_cast<void**>(&pixels));
1386
1387 uint8_t color = 0;
1388 for (int32_t j = 0; j < buf->getBuffer()->getHeight(); j++) {
1389 uint8_t* dest = pixels + (buf->getBuffer()->getStride() * j * 4);
1390 for (int32_t i = 0; i < buf->getBuffer()->getWidth(); i++) {
1391 dest[0] = color;
1392 dest[1] = color;
1393 dest[2] = color;
1394 dest[3] = 255;
1395 color++;
1396 dest += 4;
1397 }
1398 }
1399 buf->getBuffer()->unlock();
1400 }
1401
1402 mBuffer = std::make_shared<
1403 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07001404 ExternalTexture>(sp<GraphicBuffer>::make(kGreyLevels, 1,
1405 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1406 GRALLOC_USAGE_SW_READ_OFTEN |
1407 GRALLOC_USAGE_SW_WRITE_OFTEN |
1408 GRALLOC_USAGE_HW_RENDER |
1409 GRALLOC_USAGE_HW_TEXTURE,
1410 "output"),
Alec Mouri5a493722022-01-26 16:43:02 -08001411 *mRE,
1412 renderengine::impl::ExternalTexture::Usage::READABLE |
1413 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
1414 ASSERT_EQ(0, mBuffer->getBuffer()->initCheck());
1415
1416 const renderengine::LayerSettings layer{.geometry.boundaries = rect.toFloatRect(),
1417 .source =
1418 renderengine::PixelSource{
1419 .buffer =
1420 renderengine::Buffer{
1421 .buffer =
1422 std::move(buf),
1423 .usePremultipliedAlpha =
1424 true,
1425 },
1426 },
1427 .alpha = 1.0f,
1428 .sourceDataspace = sourceDataspace};
1429
1430 std::vector<renderengine::LayerSettings> layers{layer};
1431 invokeDraw(display, layers);
1432
1433 ColorSpace displayP3 = ColorSpace::DisplayP3();
1434 ColorSpace bt2020 = ColorSpace::BT2020();
1435
1436 tonemap::Metadata metadata{.displayMaxLuminance = 750.0f};
1437
1438 auto generator = [=](Point location) {
1439 const double normColor = static_cast<double>(location.x) / (kGreyLevels - 1);
1440 const vec3 rgb = vec3(normColor, normColor, normColor);
1441
1442 const vec3 linearRGB = eotf(rgb);
1443
1444 const vec3 xyz = bt2020.getRGBtoXYZ() * linearRGB;
1445
1446 const vec3 scaledXYZ = scaleOotf(xyz, kCurrentLuminanceNits);
Alec Mouri196b0f22022-03-04 22:13:48 +00001447 const auto gains =
Alec Mouri5a493722022-01-26 16:43:02 -08001448 tonemap::getToneMapper()
1449 ->lookupTonemapGain(static_cast<aidl::android::hardware::graphics::common::
1450 Dataspace>(sourceDataspace),
1451 static_cast<aidl::android::hardware::graphics::common::
1452 Dataspace>(
1453 ui::Dataspace::DISPLAY_P3),
Alec Mouri196b0f22022-03-04 22:13:48 +00001454 {tonemap::
1455 Color{.linearRGB =
1456 scaleOotf(linearRGB,
1457 kCurrentLuminanceNits),
1458 .xyz = scaledXYZ}},
Alec Mouri5a493722022-01-26 16:43:02 -08001459 metadata);
Alec Mouri196b0f22022-03-04 22:13:48 +00001460 EXPECT_EQ(1, gains.size());
1461 const double gain = gains.front();
Alec Mouri5a493722022-01-26 16:43:02 -08001462 const vec3 normalizedXYZ = scaledXYZ * gain / metadata.displayMaxLuminance;
1463
1464 const vec3 targetRGB = OETF_sRGB(displayP3.getXYZtoRGB() * normalizedXYZ) * 255;
1465 return ubyte4(static_cast<uint8_t>(targetRGB.r), static_cast<uint8_t>(targetRGB.g),
1466 static_cast<uint8_t>(targetRGB.b), 255);
1467 };
1468
1469 expectBufferColor(Rect(kGreyLevels, 1), generator, 2);
1470}
1471
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001472INSTANTIATE_TEST_SUITE_P(PerRenderEngineType, RenderEngineTest,
Alec Mouric16974e2022-09-13 17:35:48 +00001473 testing::Values(std::make_shared<SkiaGLESRenderEngineFactory>(),
Alec Mouri47bcb072023-08-15 02:02:49 +00001474 std::make_shared<SkiaVkRenderEngineFactory>()));
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001475
1476TEST_P(RenderEngineTest, drawLayers_noLayersToDraw) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001477 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001478 GTEST_SKIP();
1479 }
Alec Mouric0aae732021-01-12 13:32:18 -08001480 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001481 drawEmptyLayers();
1482}
1483
Sally Qi1fed86e2022-06-23 15:33:52 -07001484TEST_P(RenderEngineTest, drawLayers_fillRedBufferAndEmptyBuffer) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001485 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001486 GTEST_SKIP();
1487 }
Sally Qi1fed86e2022-06-23 15:33:52 -07001488 initializeRenderEngine();
1489 renderengine::DisplaySettings settings;
1490 settings.physicalDisplay = fullscreenRect();
1491 settings.clip = fullscreenRect();
1492 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1493
1494 // add a red layer
1495 renderengine::LayerSettings layerOne{
1496 .geometry.boundaries = fullscreenRect().toFloatRect(),
1497 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
1498 .alpha = 1.f,
1499 };
1500
1501 std::vector<renderengine::LayerSettings> layersFirst{layerOne};
1502 invokeDraw(settings, layersFirst);
1503 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
1504
1505 // re-draw with an empty layer above it, and we get a transparent black one
1506 std::vector<renderengine::LayerSettings> layersSecond;
1507 invokeDraw(settings, layersSecond);
1508 expectBufferColor(fullscreenRect(), 0, 0, 0, 0);
1509}
1510
Ana Krulec07b98df2021-01-07 14:38:40 -08001511TEST_P(RenderEngineTest, drawLayers_withoutBuffers_withColorTransform) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001512 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001513 GTEST_SKIP();
1514 }
Alec Mouria90a5702021-04-16 16:36:21 +00001515 initializeRenderEngine();
Ana Krulec07b98df2021-01-07 14:38:40 -08001516
1517 renderengine::DisplaySettings settings;
1518 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1519 settings.physicalDisplay = fullscreenRect();
1520 settings.clip = fullscreenRect();
1521
1522 // 255, 255, 255, 255 is full opaque white.
Alec Mouri4049b532021-10-15 20:59:33 -07001523 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
1524 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Ana Krulec07b98df2021-01-07 14:38:40 -08001525 // Create layer with given color.
1526 renderengine::LayerSettings bgLayer;
1527 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1528 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1529 bgLayer.source.solidColor = half3(backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1530 backgroundColor.b / 255.0f);
1531 bgLayer.alpha = backgroundColor.a / 255.0f;
1532 // Transform the red color.
1533 bgLayer.colorTransform = mat4(-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
1534
Sally Qi59a9f502021-10-12 18:53:23 +00001535 std::vector<renderengine::LayerSettings> layers;
1536 layers.push_back(bgLayer);
Ana Krulec07b98df2021-01-07 14:38:40 -08001537
Alec Mouric0aae732021-01-12 13:32:18 -08001538 invokeDraw(settings, layers);
Ana Krulec07b98df2021-01-07 14:38:40 -08001539
1540 // Expect to see full opaque pixel (with inverted red from the transform).
Alec Mouric0aae732021-01-12 13:32:18 -08001541 expectBufferColor(Rect(0, 0, 10, 10), 0.f, backgroundColor.g, backgroundColor.b,
Ana Krulec07b98df2021-01-07 14:38:40 -08001542 backgroundColor.a);
1543}
1544
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001545TEST_P(RenderEngineTest, drawLayers_nullOutputBuffer) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001546 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001547 GTEST_SKIP();
1548 }
Alec Mouric0aae732021-01-12 13:32:18 -08001549 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001550
Alec Mourid43ccab2019-03-13 12:23:45 -07001551 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001552 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Sally Qi59a9f502021-10-12 18:53:23 +00001553 std::vector<renderengine::LayerSettings> layers;
Alec Mourid43ccab2019-03-13 12:23:45 -07001554 renderengine::LayerSettings layer;
1555 layer.geometry.boundaries = fullscreenRect().toFloatRect();
1556 BufferSourceVariant<ForceOpaqueBufferVariant>::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
Sally Qi59a9f502021-10-12 18:53:23 +00001557 layers.push_back(layer);
Alec Mourif29700f2023-08-17 21:53:31 +00001558 ftl::Future<FenceResult> future = mRE->drawLayers(settings, layers, nullptr, base::unique_fd());
Alec Mourid43ccab2019-03-13 12:23:45 -07001559
Patrick Williams2e9748f2022-08-09 22:48:18 +00001560 ASSERT_TRUE(future.valid());
1561 auto result = future.get();
1562 ASSERT_FALSE(result.ok());
1563 ASSERT_EQ(BAD_VALUE, result.error());
Alec Mourid43ccab2019-03-13 12:23:45 -07001564}
1565
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001566TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001567 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001568 GTEST_SKIP();
1569 }
Alec Mouric0aae732021-01-12 13:32:18 -08001570 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001571 fillRedBuffer<ColorSourceVariant>();
1572}
1573
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001574TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_colorSource) {
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();
Alec Mouri1089aed2018-10-25 21:33:57 -07001579 fillGreenBuffer<ColorSourceVariant>();
1580}
1581
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001582TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001583 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001584 GTEST_SKIP();
1585 }
Alec Mouric0aae732021-01-12 13:32:18 -08001586 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001587 fillBlueBuffer<ColorSourceVariant>();
1588}
1589
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001590TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001591 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001592 GTEST_SKIP();
1593 }
Alec Mouric0aae732021-01-12 13:32:18 -08001594 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001595 fillRedTransparentBuffer<ColorSourceVariant>();
1596}
1597
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001598TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001599 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001600 GTEST_SKIP();
1601 }
Alec Mouric0aae732021-01-12 13:32:18 -08001602 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001603 fillBufferPhysicalOffset<ColorSourceVariant>();
1604}
1605
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001606TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001607 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001608 GTEST_SKIP();
1609 }
Alec Mouric0aae732021-01-12 13:32:18 -08001610 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001611 fillBufferCheckersRotate0<ColorSourceVariant>();
1612}
1613
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001614TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001615 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001616 GTEST_SKIP();
1617 }
Alec Mouric0aae732021-01-12 13:32:18 -08001618 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001619 fillBufferCheckersRotate90<ColorSourceVariant>();
1620}
1621
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001622TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001623 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001624 GTEST_SKIP();
1625 }
Alec Mouric0aae732021-01-12 13:32:18 -08001626 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001627 fillBufferCheckersRotate180<ColorSourceVariant>();
1628}
1629
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001630TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001631 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001632 GTEST_SKIP();
1633 }
Alec Mouric0aae732021-01-12 13:32:18 -08001634 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001635 fillBufferCheckersRotate270<ColorSourceVariant>();
1636}
1637
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001638TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001639 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001640 GTEST_SKIP();
1641 }
Alec Mouric0aae732021-01-12 13:32:18 -08001642 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001643 fillBufferLayerTransform<ColorSourceVariant>();
1644}
1645
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001646TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001647 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001648 GTEST_SKIP();
1649 }
Alec Mouric0aae732021-01-12 13:32:18 -08001650 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08001651 fillBufferColorTransform<ColorSourceVariant>();
1652}
1653
Sally Qi2019fd22021-11-22 10:19:04 -08001654TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_sourceDataspace) {
1655 const auto& renderEngineFactory = GetParam();
1656 // skip for non color management
Leon Scroggins III696bf932024-01-24 15:21:05 -05001657 if (!renderEngineFactory->apiSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001658 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001659 }
1660
1661 initializeRenderEngine();
1662 fillBufferColorTransformAndSourceDataspace<ColorSourceVariant>();
1663}
1664
1665TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_outputDataspace) {
1666 const auto& renderEngineFactory = GetParam();
1667 // skip for non color management
Leon Scroggins III696bf932024-01-24 15:21:05 -05001668 if (!renderEngineFactory->apiSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001669 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001670 }
1671
1672 initializeRenderEngine();
1673 fillBufferColorTransformAndOutputDataspace<ColorSourceVariant>();
1674}
1675
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001676TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001677 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001678 GTEST_SKIP();
1679 }
Alec Mouric0aae732021-01-12 13:32:18 -08001680 initializeRenderEngine();
Alec Mouri7c94edb2018-12-03 21:23:26 -08001681 fillBufferWithRoundedCorners<ColorSourceVariant>();
1682}
1683
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001684TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001685 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001686 GTEST_SKIP();
1687 }
Alec Mouric0aae732021-01-12 13:32:18 -08001688 initializeRenderEngine();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001689 fillBufferColorTransformZeroLayerAlpha<ColorSourceVariant>();
1690}
1691
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001692TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001693 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001694 GTEST_SKIP();
1695 }
Alec Mouric0aae732021-01-12 13:32:18 -08001696 initializeRenderEngine();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001697 fillBufferAndBlurBackground<ColorSourceVariant>();
1698}
1699
Alec Mourie8489fd2021-04-29 16:08:56 -07001700TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001701 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001702 GTEST_SKIP();
1703 }
Alec Mourie8489fd2021-04-29 16:08:56 -07001704 initializeRenderEngine();
1705 fillSmallLayerAndBlurBackground<ColorSourceVariant>();
1706}
1707
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001708TEST_P(RenderEngineTest, drawLayers_overlayCorners_colorSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001709 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001710 GTEST_SKIP();
1711 }
Alec Mouric0aae732021-01-12 13:32:18 -08001712 initializeRenderEngine();
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001713 overlayCorners<ColorSourceVariant>();
1714}
1715
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001716TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001717 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001718 GTEST_SKIP();
1719 }
Alec Mouric0aae732021-01-12 13:32:18 -08001720 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001721 fillRedBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1722}
1723
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001724TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001725 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001726 GTEST_SKIP();
1727 }
Alec Mouric0aae732021-01-12 13:32:18 -08001728 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001729 fillGreenBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1730}
1731
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001732TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001733 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001734 GTEST_SKIP();
1735 }
Alec Mouric0aae732021-01-12 13:32:18 -08001736 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001737 fillBlueBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1738}
1739
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001740TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001741 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001742 GTEST_SKIP();
1743 }
Alec Mouric0aae732021-01-12 13:32:18 -08001744 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001745 fillRedTransparentBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1746}
1747
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001748TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001749 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001750 GTEST_SKIP();
1751 }
Alec Mouric0aae732021-01-12 13:32:18 -08001752 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001753 fillBufferPhysicalOffset<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1754}
1755
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001756TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001757 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001758 GTEST_SKIP();
1759 }
Alec Mouric0aae732021-01-12 13:32:18 -08001760 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001761 fillBufferCheckersRotate0<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1762}
1763
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001764TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001765 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001766 GTEST_SKIP();
1767 }
Alec Mouric0aae732021-01-12 13:32:18 -08001768 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001769 fillBufferCheckersRotate90<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1770}
1771
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001772TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001773 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001774 GTEST_SKIP();
1775 }
Alec Mouric0aae732021-01-12 13:32:18 -08001776 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001777 fillBufferCheckersRotate180<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1778}
1779
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001780TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001781 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001782 GTEST_SKIP();
1783 }
Alec Mouric0aae732021-01-12 13:32:18 -08001784 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001785 fillBufferCheckersRotate270<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1786}
1787
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001788TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001789 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001790 GTEST_SKIP();
1791 }
Alec Mouric0aae732021-01-12 13:32:18 -08001792 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001793 fillBufferLayerTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1794}
1795
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001796TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001797 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001798 GTEST_SKIP();
1799 }
Alec Mouric0aae732021-01-12 13:32:18 -08001800 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08001801 fillBufferColorTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1802}
1803
Sally Qi2019fd22021-11-22 10:19:04 -08001804TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndSourceDataspace_opaqueBufferSource) {
1805 const auto& renderEngineFactory = GetParam();
1806 // skip for non color management
Leon Scroggins III696bf932024-01-24 15:21:05 -05001807 if (!renderEngineFactory->apiSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001808 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001809 }
1810
1811 initializeRenderEngine();
1812 fillBufferColorTransformAndSourceDataspace<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1813}
1814
1815TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndOutputDataspace_opaqueBufferSource) {
1816 const auto& renderEngineFactory = GetParam();
1817 // skip for non color management
Leon Scroggins III696bf932024-01-24 15:21:05 -05001818 if (!renderEngineFactory->apiSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001819 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001820 }
1821
1822 initializeRenderEngine();
1823 fillBufferColorTransformAndOutputDataspace<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1824}
1825
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001826TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001827 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001828 GTEST_SKIP();
1829 }
Alec Mouric0aae732021-01-12 13:32:18 -08001830 initializeRenderEngine();
Alec Mouri7c94edb2018-12-03 21:23:26 -08001831 fillBufferWithRoundedCorners<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1832}
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001833
Alec Mouric0aae732021-01-12 13:32:18 -08001834TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001835 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001836 GTEST_SKIP();
1837 }
Alec Mouric0aae732021-01-12 13:32:18 -08001838 initializeRenderEngine();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001839 fillBufferColorTransformZeroLayerAlpha<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1840}
Alec Mouri7c94edb2018-12-03 21:23:26 -08001841
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001842TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001843 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001844 GTEST_SKIP();
1845 }
Alec Mouric0aae732021-01-12 13:32:18 -08001846 initializeRenderEngine();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001847 fillBufferAndBlurBackground<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1848}
1849
Alec Mourie8489fd2021-04-29 16:08:56 -07001850TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001851 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001852 GTEST_SKIP();
1853 }
Alec Mourie8489fd2021-04-29 16:08:56 -07001854 initializeRenderEngine();
1855 fillSmallLayerAndBlurBackground<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1856}
1857
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001858TEST_P(RenderEngineTest, drawLayers_overlayCorners_opaqueBufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001859 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001860 GTEST_SKIP();
1861 }
Alec Mouric0aae732021-01-12 13:32:18 -08001862 initializeRenderEngine();
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001863 overlayCorners<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1864}
1865
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001866TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001867 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001868 GTEST_SKIP();
1869 }
Alec Mouric0aae732021-01-12 13:32:18 -08001870 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001871 fillRedBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1872}
1873
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001874TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001875 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001876 GTEST_SKIP();
1877 }
Alec Mouric0aae732021-01-12 13:32:18 -08001878 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001879 fillGreenBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1880}
1881
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001882TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001883 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001884 GTEST_SKIP();
1885 }
Alec Mouric0aae732021-01-12 13:32:18 -08001886 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001887 fillBlueBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1888}
1889
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001890TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001891 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001892 GTEST_SKIP();
1893 }
Alec Mouric0aae732021-01-12 13:32:18 -08001894 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001895 fillRedTransparentBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1896}
1897
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001898TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001899 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001900 GTEST_SKIP();
1901 }
Alec Mouric0aae732021-01-12 13:32:18 -08001902 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001903 fillBufferPhysicalOffset<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1904}
1905
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001906TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001907 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001908 GTEST_SKIP();
1909 }
Alec Mouric0aae732021-01-12 13:32:18 -08001910 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001911 fillBufferCheckersRotate0<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1912}
1913
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001914TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001915 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001916 GTEST_SKIP();
1917 }
Alec Mouric0aae732021-01-12 13:32:18 -08001918 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001919 fillBufferCheckersRotate90<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1920}
1921
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001922TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001923 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001924 GTEST_SKIP();
1925 }
Alec Mouric0aae732021-01-12 13:32:18 -08001926 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001927 fillBufferCheckersRotate180<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1928}
1929
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001930TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001931 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001932 GTEST_SKIP();
1933 }
Alec Mouric0aae732021-01-12 13:32:18 -08001934 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001935 fillBufferCheckersRotate270<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1936}
1937
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001938TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001939 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001940 GTEST_SKIP();
1941 }
Alec Mouric0aae732021-01-12 13:32:18 -08001942 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001943 fillBufferLayerTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1944}
1945
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001946TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001947 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001948 GTEST_SKIP();
1949 }
Alec Mouric0aae732021-01-12 13:32:18 -08001950 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08001951 fillBufferColorTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1952}
1953
Sally Qi2019fd22021-11-22 10:19:04 -08001954TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndSourceDataspace_bufferSource) {
1955 const auto& renderEngineFactory = GetParam();
1956 // skip for non color management
Leon Scroggins III696bf932024-01-24 15:21:05 -05001957 if (!renderEngineFactory->apiSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001958 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001959 }
1960
1961 initializeRenderEngine();
1962 fillBufferColorTransformAndSourceDataspace<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1963}
1964
1965TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndOutputDataspace_bufferSource) {
1966 const auto& renderEngineFactory = GetParam();
1967 // skip for non color management
Leon Scroggins III696bf932024-01-24 15:21:05 -05001968 if (!renderEngineFactory->apiSupported()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001969 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001970 }
1971
1972 initializeRenderEngine();
1973 fillBufferColorTransformAndOutputDataspace<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1974}
1975
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001976TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001977 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001978 GTEST_SKIP();
1979 }
Alec Mouric0aae732021-01-12 13:32:18 -08001980 initializeRenderEngine();
Alec Mouri7c94edb2018-12-03 21:23:26 -08001981 fillBufferWithRoundedCorners<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1982}
1983
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001984TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001985 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001986 GTEST_SKIP();
1987 }
Alec Mouric0aae732021-01-12 13:32:18 -08001988 initializeRenderEngine();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001989 fillBufferColorTransformZeroLayerAlpha<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1990}
1991
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001992TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05001993 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06001994 GTEST_SKIP();
1995 }
Alec Mouric0aae732021-01-12 13:32:18 -08001996 initializeRenderEngine();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001997 fillBufferAndBlurBackground<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1998}
1999
Alec Mourie8489fd2021-04-29 16:08:56 -07002000TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002001 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002002 GTEST_SKIP();
2003 }
Alec Mourie8489fd2021-04-29 16:08:56 -07002004 initializeRenderEngine();
2005 fillSmallLayerAndBlurBackground<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2006}
2007
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002008TEST_P(RenderEngineTest, drawLayers_overlayCorners_bufferSource) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002009 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002010 GTEST_SKIP();
2011 }
Alec Mouric0aae732021-01-12 13:32:18 -08002012 initializeRenderEngine();
Alec Mourie7d1d4a2019-02-05 01:13:46 +00002013 overlayCorners<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2014}
2015
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002016TEST_P(RenderEngineTest, drawLayers_fillBufferTextureTransform) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002017 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002018 GTEST_SKIP();
2019 }
Alec Mouric0aae732021-01-12 13:32:18 -08002020 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002021 fillBufferTextureTransform();
2022}
2023
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002024TEST_P(RenderEngineTest, drawLayers_fillBuffer_premultipliesAlpha) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002025 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002026 GTEST_SKIP();
2027 }
Alec Mouric0aae732021-01-12 13:32:18 -08002028 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002029 fillBufferWithPremultiplyAlpha();
2030}
2031
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002032TEST_P(RenderEngineTest, drawLayers_fillBuffer_withoutPremultiplyingAlpha) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002033 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002034 GTEST_SKIP();
2035 }
Alec Mouric0aae732021-01-12 13:32:18 -08002036 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002037 fillBufferWithoutPremultiplyAlpha();
2038}
2039
Alec Mouribd17b3b2020-12-17 11:08:30 -08002040TEST_P(RenderEngineTest, drawLayers_fillShadow_castsWithoutCasterLayer) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002041 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002042 GTEST_SKIP();
2043 }
Alec Mouric0aae732021-01-12 13:32:18 -08002044 initializeRenderEngine();
Alec Mouribd17b3b2020-12-17 11:08:30 -08002045
Alec Mouri4049b532021-10-15 20:59:33 -07002046 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2047 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Alec Mouribd17b3b2020-12-17 11:08:30 -08002048 const float shadowLength = 5.0f;
2049 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2050 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
Vishnu Naird9e4f462023-10-06 04:05:45 +00002051 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2052 shadowLength, false /* casterIsTranslucent */);
Alec Mouribd17b3b2020-12-17 11:08:30 -08002053
2054 drawShadowWithoutCaster(casterBounds.toFloatRect(), settings, backgroundColor);
2055 expectShadowColorWithoutCaster(casterBounds.toFloatRect(), settings, backgroundColor);
2056}
2057
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002058TEST_P(RenderEngineTest, drawLayers_fillShadow_casterLayerMinSize) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002059 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002060 GTEST_SKIP();
2061 }
Alec Mouric0aae732021-01-12 13:32:18 -08002062 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002063
Alec Mouri4049b532021-10-15 20:59:33 -07002064 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2065 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2066 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2067 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002068 const float shadowLength = 5.0f;
2069 Rect casterBounds(1, 1);
2070 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2071 renderengine::LayerSettings castingLayer;
2072 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2073 castingLayer.alpha = 1.0f;
Vishnu Naird9e4f462023-10-06 04:05:45 +00002074 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2075 shadowLength, false /* casterIsTranslucent */);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002076
2077 drawShadow<ColorSourceVariant>(castingLayer, settings, casterColor, backgroundColor);
2078 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2079}
2080
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002081TEST_P(RenderEngineTest, drawLayers_fillShadow_casterColorLayer) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002082 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002083 GTEST_SKIP();
2084 }
Alec Mouric0aae732021-01-12 13:32:18 -08002085 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002086
Alec Mouri4049b532021-10-15 20:59:33 -07002087 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2088 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2089 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2090 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002091 const float shadowLength = 5.0f;
2092 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2093 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2094 renderengine::LayerSettings castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002095 castingLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002096 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2097 castingLayer.alpha = 1.0f;
Vishnu Naird9e4f462023-10-06 04:05:45 +00002098 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2099 shadowLength, false /* casterIsTranslucent */);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002100
2101 drawShadow<ColorSourceVariant>(castingLayer, settings, casterColor, backgroundColor);
2102 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2103}
2104
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002105TEST_P(RenderEngineTest, drawLayers_fillShadow_casterOpaqueBufferLayer) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002106 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002107 GTEST_SKIP();
2108 }
Alec Mouric0aae732021-01-12 13:32:18 -08002109 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002110
Alec Mouri4049b532021-10-15 20:59:33 -07002111 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2112 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2113 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2114 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002115 const float shadowLength = 5.0f;
2116 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2117 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2118 renderengine::LayerSettings castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002119 castingLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002120 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2121 castingLayer.alpha = 1.0f;
Vishnu Naird9e4f462023-10-06 04:05:45 +00002122 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2123 shadowLength, false /* casterIsTranslucent */);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002124
2125 drawShadow<BufferSourceVariant<ForceOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2126 backgroundColor);
2127 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2128}
2129
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002130TEST_P(RenderEngineTest, drawLayers_fillShadow_casterWithRoundedCorner) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002131 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002132 GTEST_SKIP();
2133 }
Alec Mouric0aae732021-01-12 13:32:18 -08002134 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002135
Alec Mouri4049b532021-10-15 20:59:33 -07002136 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2137 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2138 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2139 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002140 const float shadowLength = 5.0f;
2141 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2142 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2143 renderengine::LayerSettings castingLayer;
2144 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002145 castingLayer.geometry.roundedCornersRadius = {3.0f, 3.0f};
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002146 castingLayer.geometry.roundedCornersCrop = casterBounds.toFloatRect();
2147 castingLayer.alpha = 1.0f;
Vishnu Naird9e4f462023-10-06 04:05:45 +00002148 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2149 shadowLength, false /* casterIsTranslucent */);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002150
2151 drawShadow<BufferSourceVariant<ForceOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2152 backgroundColor);
2153 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2154}
2155
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002156TEST_P(RenderEngineTest, drawLayers_fillShadow_translucentCasterWithAlpha) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002157 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002158 GTEST_SKIP();
2159 }
Alec Mouric0aae732021-01-12 13:32:18 -08002160 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002161
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002162 const ubyte4 casterColor(255, 0, 0, 255);
2163 const ubyte4 backgroundColor(255, 255, 255, 255);
2164 const float shadowLength = 5.0f;
2165 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2166 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2167 renderengine::LayerSettings castingLayer;
2168 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2169 castingLayer.alpha = 0.5f;
Vishnu Naird9e4f462023-10-06 04:05:45 +00002170 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2171 shadowLength, true /* casterIsTranslucent */);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002172
2173 drawShadow<BufferSourceVariant<RelaxOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2174 backgroundColor);
2175
2176 // verify only the background since the shadow will draw behind the caster
2177 const float shadowInset = settings.length * -1.0f;
2178 const Rect casterWithShadow =
2179 Rect(casterBounds).inset(shadowInset, shadowInset, shadowInset, shadowInset);
2180 const Region backgroundRegion = Region(fullscreenRect()).subtractSelf(casterWithShadow);
2181 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
2182 backgroundColor.a);
2183}
2184
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002185TEST_P(RenderEngineTest, cleanupPostRender_cleansUpOnce) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002186 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002187 GTEST_SKIP();
2188 }
Alec Mouric0aae732021-01-12 13:32:18 -08002189 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002190
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002191 renderengine::DisplaySettings settings;
2192 settings.physicalDisplay = fullscreenRect();
2193 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002194 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002195
Sally Qi59a9f502021-10-12 18:53:23 +00002196 std::vector<renderengine::LayerSettings> layers;
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002197 renderengine::LayerSettings layer;
2198 layer.geometry.boundaries = fullscreenRect().toFloatRect();
2199 BufferSourceVariant<ForceOpaqueBufferVariant>::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
2200 layer.alpha = 1.0;
Sally Qi59a9f502021-10-12 18:53:23 +00002201 layers.push_back(layer);
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002202
Patrick Williams2e9748f2022-08-09 22:48:18 +00002203 ftl::Future<FenceResult> futureOne =
Alec Mourif29700f2023-08-17 21:53:31 +00002204 mRE->drawLayers(settings, layers, mBuffer, base::unique_fd());
Patrick Williams2e9748f2022-08-09 22:48:18 +00002205 ASSERT_TRUE(futureOne.valid());
2206 auto resultOne = futureOne.get();
2207 ASSERT_TRUE(resultOne.ok());
2208 auto fenceOne = resultOne.value();
Sally Qi4cabdd02021-08-05 16:45:57 -07002209
Patrick Williams2e9748f2022-08-09 22:48:18 +00002210 ftl::Future<FenceResult> futureTwo =
Alec Mourif29700f2023-08-17 21:53:31 +00002211 mRE->drawLayers(settings, layers, mBuffer, base::unique_fd(fenceOne->dup()));
Patrick Williams2e9748f2022-08-09 22:48:18 +00002212 ASSERT_TRUE(futureTwo.valid());
2213 auto resultTwo = futureTwo.get();
2214 ASSERT_TRUE(resultTwo.ok());
2215 auto fenceTwo = resultTwo.value();
2216 fenceTwo->waitForever(LOG_TAG);
Derek Sollenbergerec411212021-08-25 10:54:47 -04002217
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002218 // Only cleanup the first time.
Ian Elliott1f0911e2022-09-09 16:31:47 -06002219 if (mRE->canSkipPostRenderCleanup()) {
2220 // Skia's Vk backend may keep the texture alive beyond drawLayersInternal, so
2221 // it never gets added to the cleanup list. In those cases, we can skip.
Leon Scroggins III696bf932024-01-24 15:21:05 -05002222 EXPECT_TRUE(GetParam()->graphicsApi() == renderengine::RenderEngine::GraphicsApi::VK);
Ian Elliott1f0911e2022-09-09 16:31:47 -06002223 } else {
2224 mRE->cleanupPostRender();
2225 EXPECT_TRUE(mRE->canSkipPostRenderCleanup());
2226 }
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002227}
2228
Ana Krulecf9a15d92020-12-11 08:35:00 -08002229TEST_P(RenderEngineTest, testRoundedCornersCrop) {
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 Krulecf9a15d92020-12-11 08:35:00 -08002234
2235 renderengine::DisplaySettings settings;
2236 settings.physicalDisplay = fullscreenRect();
2237 settings.clip = fullscreenRect();
2238 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2239
Sally Qi59a9f502021-10-12 18:53:23 +00002240 std::vector<renderengine::LayerSettings> layers;
Ana Krulecf9a15d92020-12-11 08:35:00 -08002241
2242 renderengine::LayerSettings redLayer;
2243 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2244 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002245 redLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
2246
Ana Krulecf9a15d92020-12-11 08:35:00 -08002247 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2248 // Red background.
2249 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2250 redLayer.alpha = 1.0f;
2251
Sally Qi59a9f502021-10-12 18:53:23 +00002252 layers.push_back(redLayer);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002253
2254 // Green layer with 1/3 size.
2255 renderengine::LayerSettings greenLayer;
2256 greenLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2257 greenLayer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002258 greenLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
Ana Krulecf9a15d92020-12-11 08:35:00 -08002259 // Bottom right corner is not going to be rounded.
2260 greenLayer.geometry.roundedCornersCrop =
2261 Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3, DEFAULT_DISPLAY_HEIGHT,
2262 DEFAULT_DISPLAY_HEIGHT)
2263 .toFloatRect();
2264 greenLayer.source.solidColor = half3(0.0f, 1.0f, 0.0f);
2265 greenLayer.alpha = 1.0f;
2266
Sally Qi59a9f502021-10-12 18:53:23 +00002267 layers.push_back(greenLayer);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002268
Alec Mouric0aae732021-01-12 13:32:18 -08002269 invokeDraw(settings, layers);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002270
2271 // Corners should be ignored...
2272 // Screen size: width is 128, height is 256.
2273 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 0);
2274 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, 0, DEFAULT_DISPLAY_WIDTH, 1), 0, 0, 0, 0);
2275 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT - 1, 1, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
2276 // Bottom right corner is kept out of the clipping, and it's green.
2277 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1,
2278 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
2279 0, 255, 0, 255);
2280}
2281
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002282TEST_P(RenderEngineTest, testRoundedCornersParentCrop) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002283 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002284 GTEST_SKIP();
2285 }
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002286 initializeRenderEngine();
2287
2288 renderengine::DisplaySettings settings;
2289 settings.physicalDisplay = fullscreenRect();
2290 settings.clip = fullscreenRect();
2291 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2292
Sally Qi59a9f502021-10-12 18:53:23 +00002293 std::vector<renderengine::LayerSettings> layers;
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002294
2295 renderengine::LayerSettings redLayer;
2296 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2297 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002298 redLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002299 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2300 // Red background.
2301 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2302 redLayer.alpha = 1.0f;
2303
Sally Qi59a9f502021-10-12 18:53:23 +00002304 layers.push_back(redLayer);
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002305
2306 // Green layer with 1/2 size with parent crop rect.
2307 renderengine::LayerSettings greenLayer = redLayer;
2308 greenLayer.geometry.boundaries =
2309 FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT / 2);
2310 greenLayer.source.solidColor = half3(0.0f, 1.0f, 0.0f);
2311
Sally Qi59a9f502021-10-12 18:53:23 +00002312 layers.push_back(greenLayer);
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002313
2314 invokeDraw(settings, layers);
2315
2316 // Due to roundedCornersRadius, the corners are untouched.
2317 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2318 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2319 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2320 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2321
2322 // top middle should be green and the bottom middle red
2323 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, 0), 0, 255, 0, 255);
2324 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0, 255);
2325
2326 // the bottom edge of the green layer should not be rounded
2327 expectBufferColor(Point(0, (DEFAULT_DISPLAY_HEIGHT / 2) - 1), 0, 255, 0, 255);
2328}
2329
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002330TEST_P(RenderEngineTest, testRoundedCornersParentCropSmallBounds) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002331 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002332 GTEST_SKIP();
2333 }
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002334 initializeRenderEngine();
2335
2336 renderengine::DisplaySettings settings;
2337 settings.physicalDisplay = fullscreenRect();
2338 settings.clip = fullscreenRect();
2339 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2340
Sally Qi59a9f502021-10-12 18:53:23 +00002341 std::vector<renderengine::LayerSettings> layers;
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002342
2343 renderengine::LayerSettings redLayer;
2344 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2345 redLayer.geometry.boundaries = FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, 32);
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002346 redLayer.geometry.roundedCornersRadius = {64.0f, 64.0f};
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002347 redLayer.geometry.roundedCornersCrop = FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, 128);
2348 // Red background.
2349 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2350 redLayer.alpha = 1.0f;
2351
Sally Qi59a9f502021-10-12 18:53:23 +00002352 layers.push_back(redLayer);
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002353 invokeDraw(settings, layers);
2354
2355 // Due to roundedCornersRadius, the top corners are untouched.
2356 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2357 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2358
2359 // ensure that the entire height of the red layer was clipped by the rounded corners crop.
2360 expectBufferColor(Point(0, 31), 0, 0, 0, 0);
2361 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 31), 0, 0, 0, 0);
2362
2363 // the bottom middle should be red
2364 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, 31), 255, 0, 0, 255);
2365}
2366
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002367TEST_P(RenderEngineTest, testRoundedCornersXY) {
Leon Scroggins III9ba31e32024-01-25 11:40:26 -05002368 if (!GetParam()->apiSupported()) {
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002369 GTEST_SKIP();
2370 }
2371
2372 initializeRenderEngine();
2373
2374 renderengine::DisplaySettings settings;
2375 settings.physicalDisplay = fullscreenRect();
2376 settings.clip = fullscreenRect();
2377 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2378
2379 std::vector<renderengine::LayerSettings> layers;
2380
2381 renderengine::LayerSettings redLayer;
2382 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2383 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
2384 redLayer.geometry.roundedCornersRadius = {5.0f, 20.0f};
2385 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2386 // Red background.
2387 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2388 redLayer.alpha = 1.0f;
2389
2390 layers.push_back(redLayer);
2391
2392 invokeDraw(settings, layers);
2393
2394 // Due to roundedCornersRadius, the corners are untouched.
2395 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2396 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2397 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2398 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2399
2400 // Y-axis draws a larger radius, check that its untouched as well
2401 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 5), 0, 0, 0, 0);
2402 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 5), 0, 0, 0, 0);
2403 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 5), 0, 0, 0, 0);
2404 expectBufferColor(Point(0, 5), 0, 0, 0, 0);
2405
2406 // middle should be red
2407 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0, 255);
2408}
2409
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002410TEST_P(RenderEngineTest, testClear) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002411 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002412 GTEST_SKIP();
2413 }
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002414 initializeRenderEngine();
2415
2416 const auto rect = fullscreenRect();
2417 const renderengine::DisplaySettings display{
2418 .physicalDisplay = rect,
2419 .clip = rect,
2420 };
2421
2422 const renderengine::LayerSettings redLayer{
2423 .geometry.boundaries = rect.toFloatRect(),
2424 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
2425 .alpha = 1.0f,
2426 };
2427
2428 // This mimics prepareClearClientComposition. This layer should overwrite
2429 // the redLayer, so that the buffer is transparent, rather than red.
2430 const renderengine::LayerSettings clearLayer{
2431 .geometry.boundaries = rect.toFloatRect(),
2432 .source.solidColor = half3(0.0f, 0.0f, 0.0f),
2433 .alpha = 0.0f,
2434 .disableBlending = true,
2435 };
2436
Sally Qi59a9f502021-10-12 18:53:23 +00002437 std::vector<renderengine::LayerSettings> layers{redLayer, clearLayer};
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002438 invokeDraw(display, layers);
2439 expectBufferColor(rect, 0, 0, 0, 0);
2440}
2441
2442TEST_P(RenderEngineTest, testDisableBlendingBuffer) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002443 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002444 GTEST_SKIP();
2445 }
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002446 initializeRenderEngine();
2447
2448 const auto rect = Rect(0, 0, 1, 1);
2449 const renderengine::DisplaySettings display{
2450 .physicalDisplay = rect,
2451 .clip = rect,
2452 };
2453
2454 const renderengine::LayerSettings redLayer{
2455 .geometry.boundaries = rect.toFloatRect(),
2456 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
2457 .alpha = 1.0f,
2458 };
2459
2460 // The next layer will overwrite redLayer with a GraphicBuffer that is green
2461 // applied with a translucent alpha.
Alec Mouria90a5702021-04-16 16:36:21 +00002462 const auto buf = allocateSourceBuffer(1, 1);
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002463 {
2464 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00002465 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2466 reinterpret_cast<void**>(&pixels));
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002467 pixels[0] = 0;
2468 pixels[1] = 255;
2469 pixels[2] = 0;
2470 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00002471 buf->getBuffer()->unlock();
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002472 }
2473
2474 const renderengine::LayerSettings greenLayer{
2475 .geometry.boundaries = rect.toFloatRect(),
2476 .source =
2477 renderengine::PixelSource{
2478 .buffer =
2479 renderengine::Buffer{
2480 .buffer = buf,
2481 .usePremultipliedAlpha = true,
2482 },
2483 },
2484 .alpha = 0.5f,
2485 .disableBlending = true,
2486 };
2487
Sally Qi59a9f502021-10-12 18:53:23 +00002488 std::vector<renderengine::LayerSettings> layers{redLayer, greenLayer};
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002489 invokeDraw(display, layers);
2490 expectBufferColor(rect, 0, 128, 0, 128);
2491}
2492
Tianhao Yao67dd7122022-02-22 17:48:33 +00002493TEST_P(RenderEngineTest, testBorder) {
Leon Scroggins III9ba31e32024-01-25 11:40:26 -05002494 if (!GetParam()->apiSupported()) {
Tianhao Yao67dd7122022-02-22 17:48:33 +00002495 GTEST_SKIP();
2496 }
2497
Tianhao Yao67dd7122022-02-22 17:48:33 +00002498 initializeRenderEngine();
2499
2500 const ui::Dataspace dataspace = ui::Dataspace::V0_SRGB;
2501
2502 const auto displayRect = Rect(1080, 2280);
2503 renderengine::DisplaySettings display{
2504 .physicalDisplay = displayRect,
2505 .clip = displayRect,
2506 .outputDataspace = dataspace,
2507 };
2508 display.borderInfoList.clear();
2509 renderengine::BorderRenderInfo info;
2510 info.combinedRegion = Region(Rect(99, 99, 199, 199));
Tianhao Yao10cea3c2022-03-30 01:37:22 +00002511 info.width = 20.0f;
2512 info.color = half4{1.0f, 128.0f / 255.0f, 0.0f, 1.0f};
Tianhao Yao67dd7122022-02-22 17:48:33 +00002513 display.borderInfoList.emplace_back(info);
2514
2515 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2516 const renderengine::LayerSettings greenLayer{
2517 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2518 .source =
2519 renderengine::PixelSource{
2520 .buffer =
2521 renderengine::Buffer{
2522 .buffer = greenBuffer,
2523 .usePremultipliedAlpha = true,
2524 },
2525 },
2526 .alpha = 1.0f,
2527 .sourceDataspace = dataspace,
2528 .whitePointNits = 200.f,
2529 };
2530
2531 std::vector<renderengine::LayerSettings> layers;
2532 layers.emplace_back(greenLayer);
2533 invokeDraw(display, layers);
2534
2535 expectBufferColor(Rect(99, 99, 101, 101), 255, 128, 0, 255, 1);
2536}
2537
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002538TEST_P(RenderEngineTest, testDimming) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002539 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002540 GTEST_SKIP();
2541 }
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002542 initializeRenderEngine();
2543
Alec Mouri85065692022-03-18 00:58:26 +00002544 const ui::Dataspace dataspace = ui::Dataspace::V0_SRGB_LINEAR;
2545
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002546 const auto displayRect = Rect(3, 1);
2547 const renderengine::DisplaySettings display{
2548 .physicalDisplay = displayRect,
2549 .clip = displayRect,
Alec Mouri85065692022-03-18 00:58:26 +00002550 .outputDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002551 .targetLuminanceNits = 1000.f,
2552 };
2553
2554 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2555 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2556 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2557
2558 const renderengine::LayerSettings greenLayer{
2559 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2560 .source =
2561 renderengine::PixelSource{
2562 .buffer =
2563 renderengine::Buffer{
2564 .buffer = greenBuffer,
2565 .usePremultipliedAlpha = true,
2566 },
2567 },
2568 .alpha = 1.0f,
Alec Mouri85065692022-03-18 00:58:26 +00002569 .sourceDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002570 .whitePointNits = 200.f,
2571 };
2572
2573 const renderengine::LayerSettings blueLayer{
2574 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2575 .source =
2576 renderengine::PixelSource{
2577 .buffer =
2578 renderengine::Buffer{
2579 .buffer = blueBuffer,
2580 .usePremultipliedAlpha = true,
2581 },
2582 },
2583 .alpha = 1.0f,
Alec Mouri85065692022-03-18 00:58:26 +00002584 .sourceDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002585 .whitePointNits = 1000.f / 51.f,
2586 };
2587
2588 const renderengine::LayerSettings redLayer{
2589 .geometry.boundaries = FloatRect(2.f, 0.f, 3.f, 1.f),
2590 .source =
2591 renderengine::PixelSource{
2592 .buffer =
2593 renderengine::Buffer{
2594 .buffer = redBuffer,
2595 .usePremultipliedAlpha = true,
2596 },
2597 },
2598 .alpha = 1.0f,
Alec Mouri85065692022-03-18 00:58:26 +00002599 .sourceDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002600 // When the white point is not set for a layer, just ignore it and treat it as the same
2601 // as the max layer
2602 .whitePointNits = -1.f,
2603 };
2604
2605 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer, redLayer};
2606 invokeDraw(display, layers);
2607
2608 expectBufferColor(Rect(1, 1), 0, 51, 0, 255, 1);
2609 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 5, 255, 1);
2610 expectBufferColor(Rect(2, 0, 3, 1), 51, 0, 0, 255, 1);
2611}
2612
Alec Mouri85065692022-03-18 00:58:26 +00002613TEST_P(RenderEngineTest, testDimming_inGammaSpace) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002614 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002615 GTEST_SKIP();
2616 }
Alec Mouri85065692022-03-18 00:58:26 +00002617 initializeRenderEngine();
2618
2619 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2620 ui::Dataspace::TRANSFER_GAMMA2_2 |
2621 ui::Dataspace::RANGE_FULL);
2622
2623 const auto displayRect = Rect(3, 1);
2624 const renderengine::DisplaySettings display{
2625 .physicalDisplay = displayRect,
2626 .clip = displayRect,
2627 .outputDataspace = dataspace,
2628 .targetLuminanceNits = 1000.f,
2629 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2630 };
2631
2632 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2633 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2634 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2635
2636 const renderengine::LayerSettings greenLayer{
2637 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2638 .source =
2639 renderengine::PixelSource{
2640 .buffer =
2641 renderengine::Buffer{
2642 .buffer = greenBuffer,
2643 .usePremultipliedAlpha = true,
2644 },
2645 },
2646 .alpha = 1.0f,
2647 .sourceDataspace = dataspace,
2648 .whitePointNits = 200.f,
2649 };
2650
2651 const renderengine::LayerSettings blueLayer{
2652 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2653 .source =
2654 renderengine::PixelSource{
2655 .buffer =
2656 renderengine::Buffer{
2657 .buffer = blueBuffer,
2658 .usePremultipliedAlpha = true,
2659 },
2660 },
2661 .alpha = 1.0f,
2662 .sourceDataspace = dataspace,
2663 .whitePointNits = 1000.f / 51.f,
2664 };
2665
2666 const renderengine::LayerSettings redLayer{
2667 .geometry.boundaries = FloatRect(2.f, 0.f, 3.f, 1.f),
2668 .source =
2669 renderengine::PixelSource{
2670 .buffer =
2671 renderengine::Buffer{
2672 .buffer = redBuffer,
2673 .usePremultipliedAlpha = true,
2674 },
2675 },
2676 .alpha = 1.0f,
2677 .sourceDataspace = dataspace,
2678 // When the white point is not set for a layer, just ignore it and treat it as the same
2679 // as the max layer
2680 .whitePointNits = -1.f,
2681 };
2682
2683 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer, redLayer};
2684 invokeDraw(display, layers);
2685
2686 expectBufferColor(Rect(1, 1), 0, 122, 0, 255, 1);
2687 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 42, 255, 1);
2688 expectBufferColor(Rect(2, 0, 3, 1), 122, 0, 0, 255, 1);
2689}
2690
Alec Mouri9bcd1d12022-04-21 22:16:56 +00002691TEST_P(RenderEngineTest, testDimming_inGammaSpace_withDisplayColorTransform) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002692 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002693 GTEST_SKIP();
2694 }
Alec Mouri9bcd1d12022-04-21 22:16:56 +00002695 initializeRenderEngine();
2696
2697 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2698 ui::Dataspace::TRANSFER_GAMMA2_2 |
2699 ui::Dataspace::RANGE_FULL);
2700
2701 const auto displayRect = Rect(3, 1);
2702 const renderengine::DisplaySettings display{
2703 .physicalDisplay = displayRect,
2704 .clip = displayRect,
2705 .outputDataspace = dataspace,
2706 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
2707 .targetLuminanceNits = 1000.f,
2708 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2709 };
2710
2711 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2712 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2713 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2714
2715 const renderengine::LayerSettings greenLayer{
2716 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2717 .source =
2718 renderengine::PixelSource{
2719 .buffer =
2720 renderengine::Buffer{
2721 .buffer = greenBuffer,
2722 .usePremultipliedAlpha = true,
2723 },
2724 },
2725 .alpha = 1.0f,
2726 .sourceDataspace = dataspace,
2727 .whitePointNits = 200.f,
2728 };
2729
2730 const renderengine::LayerSettings redLayer{
2731 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2732 .source =
2733 renderengine::PixelSource{
2734 .buffer =
2735 renderengine::Buffer{
2736 .buffer = redBuffer,
2737 .usePremultipliedAlpha = true,
2738 },
2739 },
2740 .alpha = 1.0f,
2741 .sourceDataspace = dataspace,
2742 // When the white point is not set for a layer, just ignore it and treat it as the same
2743 // as the max layer
2744 .whitePointNits = -1.f,
2745 };
2746
2747 std::vector<renderengine::LayerSettings> layers{greenLayer, redLayer};
2748 invokeDraw(display, layers);
2749
2750 expectBufferColor(Rect(1, 1), 0, 0, 0, 255, 1);
2751 expectBufferColor(Rect(1, 0, 2, 1), 0, 122, 0, 255, 1);
2752}
2753
2754TEST_P(RenderEngineTest, testDimming_inGammaSpace_withDisplayColorTransform_deviceHandles) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002755 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002756 GTEST_SKIP();
2757 }
Alec Mouri9bcd1d12022-04-21 22:16:56 +00002758 initializeRenderEngine();
2759
2760 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2761 ui::Dataspace::TRANSFER_GAMMA2_2 |
2762 ui::Dataspace::RANGE_FULL);
2763
2764 const auto displayRect = Rect(3, 1);
2765 const renderengine::DisplaySettings display{
2766 .physicalDisplay = displayRect,
2767 .clip = displayRect,
2768 .outputDataspace = dataspace,
2769 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
2770 .deviceHandlesColorTransform = true,
2771 .targetLuminanceNits = 1000.f,
2772 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2773 };
2774
2775 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2776 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2777 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2778
2779 const renderengine::LayerSettings greenLayer{
2780 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2781 .source =
2782 renderengine::PixelSource{
2783 .buffer =
2784 renderengine::Buffer{
2785 .buffer = greenBuffer,
2786 .usePremultipliedAlpha = true,
2787 },
2788 },
2789 .alpha = 1.0f,
2790 .sourceDataspace = dataspace,
2791 .whitePointNits = 200.f,
2792 };
2793
2794 const renderengine::LayerSettings redLayer{
2795 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2796 .source =
2797 renderengine::PixelSource{
2798 .buffer =
2799 renderengine::Buffer{
2800 .buffer = redBuffer,
2801 .usePremultipliedAlpha = true,
2802 },
2803 },
2804 .alpha = 1.0f,
2805 .sourceDataspace = dataspace,
2806 // When the white point is not set for a layer, just ignore it and treat it as the same
2807 // as the max layer
2808 .whitePointNits = -1.f,
2809 };
2810
2811 std::vector<renderengine::LayerSettings> layers{greenLayer, redLayer};
2812 invokeDraw(display, layers);
2813
2814 expectBufferColor(Rect(1, 1), 0, 122, 0, 255, 1);
2815 expectBufferColor(Rect(1, 0, 2, 1), 122, 0, 0, 255, 1);
2816}
2817
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002818TEST_P(RenderEngineTest, testDimming_withoutTargetLuminance) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002819 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002820 GTEST_SKIP();
2821 }
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002822 initializeRenderEngine();
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002823
2824 const auto displayRect = Rect(2, 1);
2825 const renderengine::DisplaySettings display{
2826 .physicalDisplay = displayRect,
2827 .clip = displayRect,
2828 .outputDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2829 .targetLuminanceNits = -1.f,
2830 };
2831
2832 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2833 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2834
2835 const renderengine::LayerSettings greenLayer{
2836 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2837 .source =
2838 renderengine::PixelSource{
2839 .buffer =
2840 renderengine::Buffer{
2841 .buffer = greenBuffer,
2842 .usePremultipliedAlpha = true,
2843 },
2844 },
2845 .alpha = 1.0f,
2846 .sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2847 .whitePointNits = 200.f,
2848 };
2849
2850 const renderengine::LayerSettings blueLayer{
2851 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2852 .source =
2853 renderengine::PixelSource{
2854 .buffer =
2855 renderengine::Buffer{
2856 .buffer = blueBuffer,
2857 .usePremultipliedAlpha = true,
2858 },
2859 },
2860 .alpha = 1.0f,
2861 .sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2862 .whitePointNits = 1000.f,
2863 };
2864
2865 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer};
2866 invokeDraw(display, layers);
2867
2868 expectBufferColor(Rect(1, 1), 0, 51, 0, 255, 1);
2869 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 255, 255);
2870}
2871
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002872TEST_P(RenderEngineTest, test_isOpaque) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002873 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002874 GTEST_SKIP();
2875 }
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002876 initializeRenderEngine();
2877
2878 const auto rect = Rect(0, 0, 1, 1);
2879 const renderengine::DisplaySettings display{
2880 .physicalDisplay = rect,
2881 .clip = rect,
2882 .outputDataspace = ui::Dataspace::DISPLAY_P3,
2883 };
2884
2885 // Create an unpremul buffer that is green with no alpha. Using isOpaque
2886 // should make the green show.
2887 const auto buf = allocateSourceBuffer(1, 1);
2888 {
2889 uint8_t* pixels;
2890 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2891 reinterpret_cast<void**>(&pixels));
2892 pixels[0] = 0;
2893 pixels[1] = 255;
2894 pixels[2] = 0;
2895 pixels[3] = 0;
2896 buf->getBuffer()->unlock();
2897 }
2898
2899 const renderengine::LayerSettings greenLayer{
2900 .geometry.boundaries = rect.toFloatRect(),
2901 .source =
2902 renderengine::PixelSource{
2903 .buffer =
2904 renderengine::Buffer{
2905 .buffer = buf,
2906 // Although the pixels are not
2907 // premultiplied in practice, this
2908 // matches the input we see.
2909 .usePremultipliedAlpha = true,
2910 .isOpaque = true,
2911 },
2912 },
2913 .alpha = 1.0f,
2914 };
2915
Sally Qi59a9f502021-10-12 18:53:23 +00002916 std::vector<renderengine::LayerSettings> layers{greenLayer};
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002917 invokeDraw(display, layers);
2918
Alec Mouri47bcb072023-08-15 02:02:49 +00002919 expectBufferColor(rect, 117, 251, 76, 255);
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002920}
Alec Mouri4049b532021-10-15 20:59:33 -07002921
Alec Mouri4049b532021-10-15 20:59:33 -07002922TEST_P(RenderEngineTest, test_tonemapPQMatches) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002923 if (!GetParam()->apiSupported()) {
Alec Mouri5a493722022-01-26 16:43:02 -08002924 GTEST_SKIP();
Alec Mouri4049b532021-10-15 20:59:33 -07002925 }
2926
Alec Mouri4049b532021-10-15 20:59:33 -07002927 initializeRenderEngine();
2928
Alec Mouri5a493722022-01-26 16:43:02 -08002929 tonemap(
2930 static_cast<ui::Dataspace>(HAL_DATASPACE_STANDARD_BT2020 |
2931 HAL_DATASPACE_TRANSFER_ST2084 | HAL_DATASPACE_RANGE_FULL),
2932 [](vec3 color) { return EOTF_PQ(color); },
2933 [](vec3 color, float) {
2934 static constexpr float kMaxPQLuminance = 10000.f;
2935 return color * kMaxPQLuminance;
2936 });
2937}
Alec Mouri4049b532021-10-15 20:59:33 -07002938
Alec Mouri5a493722022-01-26 16:43:02 -08002939TEST_P(RenderEngineTest, test_tonemapHLGMatches) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002940 if (!GetParam()->apiSupported()) {
Alec Mouri5a493722022-01-26 16:43:02 -08002941 GTEST_SKIP();
Alec Mouri4049b532021-10-15 20:59:33 -07002942 }
2943
Alec Mouri5a493722022-01-26 16:43:02 -08002944 initializeRenderEngine();
Alec Mouri4049b532021-10-15 20:59:33 -07002945
Alec Mouri5a493722022-01-26 16:43:02 -08002946 tonemap(
2947 static_cast<ui::Dataspace>(HAL_DATASPACE_STANDARD_BT2020 | HAL_DATASPACE_TRANSFER_HLG |
2948 HAL_DATASPACE_RANGE_FULL),
2949 [](vec3 color) { return EOTF_HLG(color); },
2950 [](vec3 color, float currentLuminaceNits) {
2951 static constexpr float kMaxHLGLuminance = 1000.f;
Alec Mouri7a577452022-03-04 23:41:38 +00002952 return color * kMaxHLGLuminance;
Alec Mouri5a493722022-01-26 16:43:02 -08002953 });
Alec Mouri4049b532021-10-15 20:59:33 -07002954}
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -05002955
2956TEST_P(RenderEngineTest, r8_behaves_as_mask) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05002957 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06002958 GTEST_SKIP();
2959 }
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -05002960 initializeRenderEngine();
2961
2962 const auto r8Buffer = allocateR8Buffer(2, 1);
2963 if (!r8Buffer) {
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05002964 GTEST_SKIP() << "Test is only necessary on devices that support r8";
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -05002965 return;
2966 }
2967 {
2968 uint8_t* pixels;
2969 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2970 reinterpret_cast<void**>(&pixels));
2971 // This will be drawn on top of a green buffer. We'll verify that 255
2972 // results in keeping the original green and 0 results in black.
2973 pixels[0] = 0;
2974 pixels[1] = 255;
2975 r8Buffer->getBuffer()->unlock();
2976 }
2977
2978 const auto rect = Rect(0, 0, 2, 1);
2979 const renderengine::DisplaySettings display{
2980 .physicalDisplay = rect,
2981 .clip = rect,
2982 .outputDataspace = ui::Dataspace::SRGB,
2983 };
2984
2985 const auto greenBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(0, 255, 0, 255));
2986 const renderengine::LayerSettings greenLayer{
2987 .geometry.boundaries = rect.toFloatRect(),
2988 .source =
2989 renderengine::PixelSource{
2990 .buffer =
2991 renderengine::Buffer{
2992 .buffer = greenBuffer,
2993 },
2994 },
2995 .alpha = 1.0f,
2996 };
2997 const renderengine::LayerSettings r8Layer{
2998 .geometry.boundaries = rect.toFloatRect(),
2999 .source =
3000 renderengine::PixelSource{
3001 .buffer =
3002 renderengine::Buffer{
3003 .buffer = r8Buffer,
3004 },
3005 },
3006 .alpha = 1.0f,
3007 };
3008
3009 std::vector<renderengine::LayerSettings> layers{greenLayer, r8Layer};
3010 invokeDraw(display, layers);
3011
3012 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 255);
3013 expectBufferColor(Rect(1, 0, 2, 1), 0, 255, 0, 255);
3014}
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003015
3016TEST_P(RenderEngineTest, r8_respects_color_transform) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05003017 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003018 GTEST_SKIP();
3019 }
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003020 initializeRenderEngine();
3021
3022 const auto r8Buffer = allocateR8Buffer(2, 1);
3023 if (!r8Buffer) {
3024 GTEST_SKIP() << "Test is only necessary on devices that support r8";
3025 return;
3026 }
3027 {
3028 uint8_t* pixels;
3029 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
3030 reinterpret_cast<void**>(&pixels));
3031 pixels[0] = 0;
3032 pixels[1] = 255;
3033 r8Buffer->getBuffer()->unlock();
3034 }
3035
3036 const auto rect = Rect(0, 0, 2, 1);
3037 const renderengine::DisplaySettings display{
3038 .physicalDisplay = rect,
3039 .clip = rect,
3040 .outputDataspace = ui::Dataspace::SRGB,
3041 // Verify that the R8 layer respects the color transform when
3042 // deviceHandlesColorTransform is false. This transform converts
3043 // pure red to pure green. That will occur when the R8 buffer is
3044 // 255. When the R8 buffer is 0, it will still change to black, as
3045 // with r8_behaves_as_mask.
Alec Mouri9bcd1d12022-04-21 22:16:56 +00003046 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003047 .deviceHandlesColorTransform = false,
3048 };
3049
3050 const auto redBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(255, 0, 0, 255));
3051 const renderengine::LayerSettings redLayer{
3052 .geometry.boundaries = rect.toFloatRect(),
3053 .source =
3054 renderengine::PixelSource{
3055 .buffer =
3056 renderengine::Buffer{
3057 .buffer = redBuffer,
3058 },
3059 },
3060 .alpha = 1.0f,
3061 };
3062 const renderengine::LayerSettings r8Layer{
3063 .geometry.boundaries = rect.toFloatRect(),
3064 .source =
3065 renderengine::PixelSource{
3066 .buffer =
3067 renderengine::Buffer{
3068 .buffer = r8Buffer,
3069 },
3070 },
3071 .alpha = 1.0f,
3072 };
3073
3074 std::vector<renderengine::LayerSettings> layers{redLayer, r8Layer};
3075 invokeDraw(display, layers);
3076
3077 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 255);
3078 expectBufferColor(Rect(1, 0, 2, 1), 0, 255, 0, 255);
3079}
3080
3081TEST_P(RenderEngineTest, r8_respects_color_transform_when_device_handles) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05003082 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003083 GTEST_SKIP();
3084 }
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003085 initializeRenderEngine();
3086
3087 const auto r8Buffer = allocateR8Buffer(2, 1);
3088 if (!r8Buffer) {
3089 GTEST_SKIP() << "Test is only necessary on devices that support r8";
3090 return;
3091 }
3092 {
3093 uint8_t* pixels;
3094 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
3095 reinterpret_cast<void**>(&pixels));
3096 pixels[0] = 0;
3097 pixels[1] = 255;
3098 r8Buffer->getBuffer()->unlock();
3099 }
3100
3101 const auto rect = Rect(0, 0, 2, 1);
3102 const renderengine::DisplaySettings display{
3103 .physicalDisplay = rect,
3104 .clip = rect,
3105 .outputDataspace = ui::Dataspace::SRGB,
3106 // If deviceHandlesColorTransform is true, pixels where the A8
3107 // buffer is opaque are unaffected. If the colorTransform is
3108 // invertible, pixels where the A8 buffer are transparent have the
3109 // inverse applied to them so that the DPU will convert them back to
3110 // black. Test with an arbitrary, invertible matrix.
3111 .colorTransform = mat4(1, 0, 0, 2,
3112 3, 1, 2, 5,
3113 0, 5, 3, 0,
3114 0, 1, 0, 2),
3115 .deviceHandlesColorTransform = true,
3116 };
3117
3118 const auto redBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(255, 0, 0, 255));
3119 const renderengine::LayerSettings redLayer{
3120 .geometry.boundaries = rect.toFloatRect(),
3121 .source =
3122 renderengine::PixelSource{
3123 .buffer =
3124 renderengine::Buffer{
3125 .buffer = redBuffer,
3126 },
3127 },
3128 .alpha = 1.0f,
3129 };
3130 const renderengine::LayerSettings r8Layer{
3131 .geometry.boundaries = rect.toFloatRect(),
3132 .source =
3133 renderengine::PixelSource{
3134 .buffer =
3135 renderengine::Buffer{
3136 .buffer = r8Buffer,
3137 },
3138 },
3139 .alpha = 1.0f,
3140 };
3141
3142 std::vector<renderengine::LayerSettings> layers{redLayer, r8Layer};
3143 invokeDraw(display, layers);
3144
3145 expectBufferColor(Rect(1, 0, 2, 1), 255, 0, 0, 255); // Still red.
3146 expectBufferColor(Rect(0, 0, 1, 1), 0, 70, 0, 255);
3147}
Leon Scroggins III45be9182022-04-27 10:37:11 -04003148
3149TEST_P(RenderEngineTest, primeShaderCache) {
Leon Scroggins III696bf932024-01-24 15:21:05 -05003150 if (!GetParam()->apiSupported()) {
Ian Elliott1f0911e2022-09-09 16:31:47 -06003151 GTEST_SKIP();
3152 }
Leon Scroggins III45be9182022-04-27 10:37:11 -04003153 initializeRenderEngine();
3154
Bruno BELANYIb9b5b702023-10-13 13:25:11 +00003155 auto fut = mRE->primeCache(false);
Leon Scroggins III45be9182022-04-27 10:37:11 -04003156 if (fut.valid()) {
3157 fut.wait();
3158 }
3159
Alec Mouri47bcb072023-08-15 02:02:49 +00003160 static constexpr int kMinimumExpectedShadersCompiled = 60;
Leon Scroggins III45be9182022-04-27 10:37:11 -04003161 ASSERT_GT(static_cast<skia::SkiaGLRenderEngine*>(mRE.get())->reportShadersCompiled(),
Alec Mouri47bcb072023-08-15 02:02:49 +00003162 kMinimumExpectedShadersCompiled);
Leon Scroggins III45be9182022-04-27 10:37:11 -04003163}
Derek Sollenbergerd3f60652021-06-11 15:34:36 -04003164} // namespace renderengine
Alec Mouri6e57f682018-09-29 20:45:08 -07003165} // namespace android
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08003166
3167// TODO(b/129481165): remove the #pragma below and fix conversion issues
Marin Shalamanovbed7fd32020-12-21 20:02:20 +01003168#pragma clang diagnostic pop // ignored "-Wconversion -Wextra"