blob: f2897308af51b5b73e0703d770370120737c7300 [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 Mourid43ccab2019-03-13 12:23:45 -070040#include "../gl/GLESRenderEngine.h"
Alec Mouric0aae732021-01-12 13:32:18 -080041#include "../skia/SkiaGLRenderEngine.h"
Ana Krulec9bc9dc62020-02-26 12:16:40 -080042#include "../threaded/RenderEngineThreaded.h"
Alec Mouri6e57f682018-09-29 20:45:08 -070043
Alec Mouri1089aed2018-10-25 21:33:57 -070044constexpr int DEFAULT_DISPLAY_WIDTH = 128;
45constexpr int DEFAULT_DISPLAY_HEIGHT = 256;
46constexpr int DEFAULT_DISPLAY_OFFSET = 64;
Vishnu Nair16efdbf2019-12-10 11:55:42 -080047constexpr bool WRITE_BUFFER_TO_FILE_ON_FAILURE = false;
Alec Mouri1089aed2018-10-25 21:33:57 -070048
Alec Mouri6e57f682018-09-29 20:45:08 -070049namespace android {
Derek Sollenbergerd3f60652021-06-11 15:34:36 -040050namespace renderengine {
Alec Mouri6e57f682018-09-29 20:45:08 -070051
Alec Mouri5a493722022-01-26 16:43:02 -080052namespace {
53
54double EOTF_PQ(double channel) {
55 float m1 = (2610.0 / 4096.0) / 4.0;
56 float m2 = (2523.0 / 4096.0) * 128.0;
57 float c1 = (3424.0 / 4096.0);
58 float c2 = (2413.0 / 4096.0) * 32.0;
59 float c3 = (2392.0 / 4096.0) * 32.0;
60
61 float tmp = std::pow(std::clamp(channel, 0.0, 1.0), 1.0 / m2);
62 tmp = std::fmax(tmp - c1, 0.0) / (c2 - c3 * tmp);
63 return std::pow(tmp, 1.0 / m1);
64}
65
66vec3 EOTF_PQ(vec3 color) {
67 return vec3(EOTF_PQ(color.r), EOTF_PQ(color.g), EOTF_PQ(color.b));
68}
69
70double EOTF_HLG(double channel) {
71 const float a = 0.17883277;
72 const float b = 0.28466892;
73 const float c = 0.55991073;
74 return channel <= 0.5 ? channel * channel / 3.0 : (exp((channel - c) / a) + b) / 12.0;
75}
76
77vec3 EOTF_HLG(vec3 color) {
78 return vec3(EOTF_HLG(color.r), EOTF_HLG(color.g), EOTF_HLG(color.b));
79}
80
81double OETF_sRGB(double channel) {
82 return channel <= 0.0031308 ? channel * 12.92 : (pow(channel, 1.0 / 2.4) * 1.055) - 0.055;
83}
84
85int sign(float in) {
86 return in >= 0.0 ? 1 : -1;
87}
88
89vec3 OETF_sRGB(vec3 linear) {
90 return vec3(sign(linear.r) * OETF_sRGB(linear.r), sign(linear.g) * OETF_sRGB(linear.g),
91 sign(linear.b) * OETF_sRGB(linear.b));
92}
93
Alec Mouri9bcd1d12022-04-21 22:16:56 +000094// clang-format off
95// Converts red channels to green channels, and zeroes out an existing green channel.
96static const auto kRemoveGreenAndMoveRedToGreenMat4 = mat4(0, 1, 0, 0,
97 0, 0, 0, 0,
98 0, 0, 1, 0,
99 0, 0, 0, 1);
100// clang-format on
101
Alec Mouri5a493722022-01-26 16:43:02 -0800102} // namespace
103
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800104class RenderEngineFactory {
105public:
106 virtual ~RenderEngineFactory() = default;
107
108 virtual std::string name() = 0;
Alec Mouric0aae732021-01-12 13:32:18 -0800109 virtual renderengine::RenderEngine::RenderEngineType type() = 0;
110 virtual std::unique_ptr<renderengine::RenderEngine> createRenderEngine() = 0;
111 virtual std::unique_ptr<renderengine::gl::GLESRenderEngine> createGLESRenderEngine() {
112 return nullptr;
113 }
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -0400114 virtual bool useColorManagement() const = 0;
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800115};
116
117class GLESRenderEngineFactory : public RenderEngineFactory {
118public:
119 std::string name() override { return "GLESRenderEngineFactory"; }
120
Alec Mouric0aae732021-01-12 13:32:18 -0800121 renderengine::RenderEngine::RenderEngineType type() {
122 return renderengine::RenderEngine::RenderEngineType::GLES;
123 }
124
125 std::unique_ptr<renderengine::RenderEngine> createRenderEngine() override {
126 return createGLESRenderEngine();
127 }
128
129 std::unique_ptr<renderengine::gl::GLESRenderEngine> createGLESRenderEngine() {
KaiChieh Chuang436fc192020-09-07 13:48:42 +0800130 renderengine::RenderEngineCreationArgs reCreationArgs =
Peiyong Lin4137a1d2019-10-09 10:39:09 -0700131 renderengine::RenderEngineCreationArgs::Builder()
Ana Krulec9bc9dc62020-02-26 12:16:40 -0800132 .setPixelFormat(static_cast<int>(ui::PixelFormat::RGBA_8888))
133 .setImageCacheSize(1)
134 .setUseColorManagerment(false)
135 .setEnableProtectedContext(false)
136 .setPrecacheToneMapperShaderOnly(false)
137 .setSupportsBackgroundBlur(true)
138 .setContextPriority(renderengine::RenderEngine::ContextPriority::MEDIUM)
Alec Mouric0aae732021-01-12 13:32:18 -0800139 .setRenderEngineType(type())
Alec Mourid2bcbae2021-06-28 17:02:17 -0700140 .setUseColorManagerment(useColorManagement())
KaiChieh Chuang436fc192020-09-07 13:48:42 +0800141 .build();
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800142 return renderengine::gl::GLESRenderEngine::create(reCreationArgs);
Alec Mourid43ccab2019-03-13 12:23:45 -0700143 }
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -0400144
145 bool useColorManagement() const override { return false; }
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800146};
Alec Mourid43ccab2019-03-13 12:23:45 -0700147
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800148class GLESCMRenderEngineFactory : public RenderEngineFactory {
149public:
150 std::string name() override { return "GLESCMRenderEngineFactory"; }
151
Alec Mouric0aae732021-01-12 13:32:18 -0800152 renderengine::RenderEngine::RenderEngineType type() {
153 return renderengine::RenderEngine::RenderEngineType::GLES;
154 }
155
156 std::unique_ptr<renderengine::RenderEngine> createRenderEngine() override {
157 return createGLESRenderEngine();
158 }
159
160 std::unique_ptr<renderengine::gl::GLESRenderEngine> createGLESRenderEngine() override {
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800161 renderengine::RenderEngineCreationArgs reCreationArgs =
162 renderengine::RenderEngineCreationArgs::Builder()
163 .setPixelFormat(static_cast<int>(ui::PixelFormat::RGBA_8888))
164 .setImageCacheSize(1)
165 .setEnableProtectedContext(false)
166 .setPrecacheToneMapperShaderOnly(false)
167 .setSupportsBackgroundBlur(true)
168 .setContextPriority(renderengine::RenderEngine::ContextPriority::MEDIUM)
Alec Mouric0aae732021-01-12 13:32:18 -0800169 .setRenderEngineType(type())
Alec Mourid2bcbae2021-06-28 17:02:17 -0700170 .setUseColorManagerment(useColorManagement())
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800171 .build();
172 return renderengine::gl::GLESRenderEngine::create(reCreationArgs);
173 }
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -0400174
175 bool useColorManagement() const override { return true; }
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800176};
177
Alec Mouri0eab3e82020-12-08 18:10:27 -0800178class SkiaGLESRenderEngineFactory : public RenderEngineFactory {
179public:
Alec Mouric0aae732021-01-12 13:32:18 -0800180 std::string name() override { return "SkiaGLRenderEngineFactory"; }
Alec Mouri0eab3e82020-12-08 18:10:27 -0800181
Alec Mouric0aae732021-01-12 13:32:18 -0800182 renderengine::RenderEngine::RenderEngineType type() {
183 return renderengine::RenderEngine::RenderEngineType::SKIA_GL;
184 }
185
186 std::unique_ptr<renderengine::RenderEngine> createRenderEngine() override {
Alec Mouri0eab3e82020-12-08 18:10:27 -0800187 renderengine::RenderEngineCreationArgs reCreationArgs =
188 renderengine::RenderEngineCreationArgs::Builder()
189 .setPixelFormat(static_cast<int>(ui::PixelFormat::RGBA_8888))
190 .setImageCacheSize(1)
191 .setEnableProtectedContext(false)
192 .setPrecacheToneMapperShaderOnly(false)
193 .setSupportsBackgroundBlur(true)
194 .setContextPriority(renderengine::RenderEngine::ContextPriority::MEDIUM)
Alec Mouric0aae732021-01-12 13:32:18 -0800195 .setRenderEngineType(type())
Alec Mourid2bcbae2021-06-28 17:02:17 -0700196 .setUseColorManagerment(useColorManagement())
Alec Mouri0eab3e82020-12-08 18:10:27 -0800197 .build();
Alec Mouric0aae732021-01-12 13:32:18 -0800198 return renderengine::skia::SkiaGLRenderEngine::create(reCreationArgs);
Alec Mouri0eab3e82020-12-08 18:10:27 -0800199 }
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -0400200
Alec Mourid2bcbae2021-06-28 17:02:17 -0700201 bool useColorManagement() const override { return false; }
Alec Mouri0eab3e82020-12-08 18:10:27 -0800202};
203
204class SkiaGLESCMRenderEngineFactory : public RenderEngineFactory {
205public:
Alec Mouric0aae732021-01-12 13:32:18 -0800206 std::string name() override { return "SkiaGLCMRenderEngineFactory"; }
Alec Mouri0eab3e82020-12-08 18:10:27 -0800207
Alec Mouric0aae732021-01-12 13:32:18 -0800208 renderengine::RenderEngine::RenderEngineType type() {
209 return renderengine::RenderEngine::RenderEngineType::SKIA_GL;
210 }
211
212 std::unique_ptr<renderengine::RenderEngine> createRenderEngine() override {
Alec Mouri0eab3e82020-12-08 18:10:27 -0800213 renderengine::RenderEngineCreationArgs reCreationArgs =
214 renderengine::RenderEngineCreationArgs::Builder()
215 .setPixelFormat(static_cast<int>(ui::PixelFormat::RGBA_8888))
216 .setImageCacheSize(1)
217 .setEnableProtectedContext(false)
218 .setPrecacheToneMapperShaderOnly(false)
219 .setSupportsBackgroundBlur(true)
220 .setContextPriority(renderengine::RenderEngine::ContextPriority::MEDIUM)
Alec Mouric0aae732021-01-12 13:32:18 -0800221 .setRenderEngineType(type())
Alec Mourid2bcbae2021-06-28 17:02:17 -0700222 .setUseColorManagerment(useColorManagement())
Alec Mouri0eab3e82020-12-08 18:10:27 -0800223 .build();
Alec Mouric0aae732021-01-12 13:32:18 -0800224 return renderengine::skia::SkiaGLRenderEngine::create(reCreationArgs);
Alec Mouri0eab3e82020-12-08 18:10:27 -0800225 }
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -0400226
227 bool useColorManagement() const override { return true; }
Alec Mouri0eab3e82020-12-08 18:10:27 -0800228};
229
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800230class RenderEngineTest : public ::testing::TestWithParam<std::shared_ptr<RenderEngineFactory>> {
231public:
Alec Mouria90a5702021-04-16 16:36:21 +0000232 std::shared_ptr<renderengine::ExternalTexture> allocateDefaultBuffer() {
233 return std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800234 renderengine::impl::
Alec Mouria90a5702021-04-16 16:36:21 +0000235 ExternalTexture>(new GraphicBuffer(DEFAULT_DISPLAY_WIDTH,
236 DEFAULT_DISPLAY_HEIGHT,
237 HAL_PIXEL_FORMAT_RGBA_8888, 1,
238 GRALLOC_USAGE_SW_READ_OFTEN |
239 GRALLOC_USAGE_SW_WRITE_OFTEN |
240 GRALLOC_USAGE_HW_RENDER |
241 GRALLOC_USAGE_HW_TEXTURE,
242 "output"),
243 *mRE,
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800244 renderengine::impl::ExternalTexture::Usage::READABLE |
245 renderengine::impl::ExternalTexture::Usage::
246 WRITEABLE);
Alec Mouri6e57f682018-09-29 20:45:08 -0700247 }
248
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800249 // Allocates a 1x1 buffer to fill with a solid color
Alec Mouria90a5702021-04-16 16:36:21 +0000250 std::shared_ptr<renderengine::ExternalTexture> allocateSourceBuffer(uint32_t width,
251 uint32_t height) {
252 return std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800253 renderengine::impl::
Alec Mouria90a5702021-04-16 16:36:21 +0000254 ExternalTexture>(new GraphicBuffer(width, height,
255 HAL_PIXEL_FORMAT_RGBA_8888, 1,
256 GRALLOC_USAGE_SW_READ_OFTEN |
257 GRALLOC_USAGE_SW_WRITE_OFTEN |
258 GRALLOC_USAGE_HW_TEXTURE,
259 "input"),
260 *mRE,
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800261 renderengine::impl::ExternalTexture::Usage::READABLE |
262 renderengine::impl::ExternalTexture::Usage::
263 WRITEABLE);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800264 }
265
Alec Mouricdf6cbc2021-11-01 17:21:15 -0700266 std::shared_ptr<renderengine::ExternalTexture> allocateAndFillSourceBuffer(uint32_t width,
267 uint32_t height,
268 ubyte4 color) {
269 const auto buffer = allocateSourceBuffer(width, height);
270 uint8_t* pixels;
271 buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
272 reinterpret_cast<void**>(&pixels));
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -0500273 for (uint32_t j = 0; j < height; j++) {
274 uint8_t* dst = pixels + (buffer->getBuffer()->getStride() * j * 4);
275 for (uint32_t i = 0; i < width; i++) {
276 dst[0] = color.r;
277 dst[1] = color.g;
278 dst[2] = color.b;
279 dst[3] = color.a;
280 dst += 4;
281 }
282 }
Alec Mouricdf6cbc2021-11-01 17:21:15 -0700283 buffer->getBuffer()->unlock();
284 return buffer;
285 }
286
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -0500287 std::shared_ptr<renderengine::ExternalTexture> allocateR8Buffer(int width, int height) {
288 auto buffer = new GraphicBuffer(width, height, android::PIXEL_FORMAT_R_8, 1,
289 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
290 GRALLOC_USAGE_HW_TEXTURE,
291 "r8");
292 if (buffer->initCheck() != 0) {
293 // Devices are not required to support R8.
294 return nullptr;
295 }
296 return std::make_shared<
297 renderengine::impl::ExternalTexture>(std::move(buffer), *mRE,
298 renderengine::impl::ExternalTexture::Usage::
299 READABLE);
300 }
301
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800302 RenderEngineTest() {
303 const ::testing::TestInfo* const test_info =
304 ::testing::UnitTest::GetInstance()->current_test_info();
305 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800306 }
Alec Mouri1089aed2018-10-25 21:33:57 -0700307
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800308 ~RenderEngineTest() {
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800309 if (WRITE_BUFFER_TO_FILE_ON_FAILURE && ::testing::Test::HasFailure()) {
310 writeBufferToFile("/data/texture_out_");
311 }
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800312 for (uint32_t texName : mTexNames) {
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800313 mRE->deleteTextures(1, &texName);
Alec Mouric0aae732021-01-12 13:32:18 -0800314 if (mGLESRE != nullptr) {
315 EXPECT_FALSE(mGLESRE->isTextureNameKnownForTesting(texName));
316 }
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800317 }
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800318 const ::testing::TestInfo* const test_info =
319 ::testing::UnitTest::GetInstance()->current_test_info();
320 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800321 }
322
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800323 void writeBufferToFile(const char* basename) {
324 std::string filename(basename);
325 filename.append(::testing::UnitTest::GetInstance()->current_test_info()->name());
326 filename.append(".ppm");
327 std::ofstream file(filename.c_str(), std::ios::binary);
328 if (!file.is_open()) {
329 ALOGE("Unable to open file: %s", filename.c_str());
330 ALOGE("You may need to do: \"adb shell setenforce 0\" to enable "
331 "surfaceflinger to write debug images");
332 return;
333 }
334
Alec Mouri1089aed2018-10-25 21:33:57 -0700335 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +0000336 mBuffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
337 reinterpret_cast<void**>(&pixels));
Alec Mouri1089aed2018-10-25 21:33:57 -0700338
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800339 file << "P6\n";
Alec Mouria90a5702021-04-16 16:36:21 +0000340 file << mBuffer->getBuffer()->getWidth() << "\n";
341 file << mBuffer->getBuffer()->getHeight() << "\n";
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800342 file << 255 << "\n";
343
Alec Mouria90a5702021-04-16 16:36:21 +0000344 std::vector<uint8_t> outBuffer(mBuffer->getBuffer()->getWidth() *
345 mBuffer->getBuffer()->getHeight() * 3);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800346 auto outPtr = reinterpret_cast<uint8_t*>(outBuffer.data());
347
Alec Mouria90a5702021-04-16 16:36:21 +0000348 for (int32_t j = 0; j < mBuffer->getBuffer()->getHeight(); j++) {
349 const uint8_t* src = pixels + (mBuffer->getBuffer()->getStride() * j) * 4;
350 for (int32_t i = 0; i < mBuffer->getBuffer()->getWidth(); i++) {
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800351 // Only copy R, G and B components
352 outPtr[0] = src[0];
353 outPtr[1] = src[1];
354 outPtr[2] = src[2];
355 outPtr += 3;
356
357 src += 4;
358 }
359 }
360 file.write(reinterpret_cast<char*>(outBuffer.data()), outBuffer.size());
Alec Mouria90a5702021-04-16 16:36:21 +0000361 mBuffer->getBuffer()->unlock();
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800362 }
363
364 void expectBufferColor(const Region& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
365 size_t c;
366 Rect const* rect = region.getArray(&c);
367 for (size_t i = 0; i < c; i++, rect++) {
368 expectBufferColor(*rect, r, g, b, a);
369 }
370 }
371
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -0400372 void expectBufferColor(const Point& point, uint8_t r, uint8_t g, uint8_t b, uint8_t a,
373 uint8_t tolerance = 0) {
374 expectBufferColor(Rect(point.x, point.y, point.x + 1, point.y + 1), r, g, b, a, tolerance);
375 }
376
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800377 void expectBufferColor(const Rect& rect, uint8_t r, uint8_t g, uint8_t b, uint8_t a,
378 uint8_t tolerance = 0) {
Alec Mouri4049b532021-10-15 20:59:33 -0700379 auto generator = [=](Point) { return ubyte4(r, g, b, a); };
380 expectBufferColor(rect, generator, tolerance);
381 }
382
383 using ColorGenerator = std::function<ubyte4(Point location)>;
384
385 void expectBufferColor(const Rect& rect, ColorGenerator generator, uint8_t tolerance = 0) {
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800386 auto colorCompare = [tolerance](const uint8_t* colorA, const uint8_t* colorB) {
387 auto colorBitCompare = [tolerance](uint8_t a, uint8_t b) {
388 uint8_t tmp = a >= b ? a - b : b - a;
389 return tmp <= tolerance;
390 };
391 return std::equal(colorA, colorA + 4, colorB, colorBitCompare);
Alec Mouri1089aed2018-10-25 21:33:57 -0700392 };
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800393
Alec Mouri4049b532021-10-15 20:59:33 -0700394 expectBufferColor(rect, generator, colorCompare);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800395 }
396
Alec Mouri4049b532021-10-15 20:59:33 -0700397 void expectBufferColor(const Rect& region, ColorGenerator generator,
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800398 std::function<bool(const uint8_t* a, const uint8_t* b)> colorCompare) {
399 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +0000400 mBuffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
401 reinterpret_cast<void**>(&pixels));
Alec Mouri1089aed2018-10-25 21:33:57 -0700402 int32_t maxFails = 10;
403 int32_t fails = 0;
404 for (int32_t j = 0; j < region.getHeight(); j++) {
Alec Mouria90a5702021-04-16 16:36:21 +0000405 const uint8_t* src = pixels +
406 (mBuffer->getBuffer()->getStride() * (region.top + j) + region.left) * 4;
Alec Mouri1089aed2018-10-25 21:33:57 -0700407 for (int32_t i = 0; i < region.getWidth(); i++) {
Alec Mouri4049b532021-10-15 20:59:33 -0700408 const auto location = Point(region.left + i, region.top + j);
409 const ubyte4 colors = generator(location);
410 const uint8_t expected[4] = {colors.r, colors.g, colors.b, colors.a};
411 bool colorMatches = colorCompare(src, expected);
412 EXPECT_TRUE(colorMatches)
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -0400413 << GetParam()->name().c_str() << ": "
Alec Mouri4049b532021-10-15 20:59:33 -0700414 << "pixel @ (" << location.x << ", " << location.y << "): "
415 << "expected (" << static_cast<uint32_t>(colors.r) << ", "
416 << static_cast<uint32_t>(colors.g) << ", "
417 << static_cast<uint32_t>(colors.b) << ", "
418 << static_cast<uint32_t>(colors.a) << "), "
Alec Mouri1089aed2018-10-25 21:33:57 -0700419 << "got (" << static_cast<uint32_t>(src[0]) << ", "
420 << static_cast<uint32_t>(src[1]) << ", " << static_cast<uint32_t>(src[2])
421 << ", " << static_cast<uint32_t>(src[3]) << ")";
422 src += 4;
Alec Mouri4049b532021-10-15 20:59:33 -0700423 if (!colorMatches && ++fails >= maxFails) {
Alec Mouri1089aed2018-10-25 21:33:57 -0700424 break;
425 }
426 }
427 if (fails >= maxFails) {
428 break;
429 }
430 }
Alec Mouria90a5702021-04-16 16:36:21 +0000431 mBuffer->getBuffer()->unlock();
Alec Mouri1089aed2018-10-25 21:33:57 -0700432 }
433
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800434 void expectAlpha(const Rect& rect, uint8_t a) {
Alec Mouri4049b532021-10-15 20:59:33 -0700435 auto generator = [=](Point) { return ubyte4(0, 0, 0, a); };
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800436 auto colorCompare = [](const uint8_t* colorA, const uint8_t* colorB) {
437 return colorA[3] == colorB[3];
438 };
Alec Mouri4049b532021-10-15 20:59:33 -0700439 expectBufferColor(rect, generator, colorCompare);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800440 }
441
442 void expectShadowColor(const renderengine::LayerSettings& castingLayer,
443 const renderengine::ShadowSettings& shadow, const ubyte4& casterColor,
444 const ubyte4& backgroundColor) {
445 const Rect casterRect(castingLayer.geometry.boundaries);
446 Region casterRegion = Region(casterRect);
Vishnu Nair50c0afe2022-07-11 15:04:07 -0700447 const float casterCornerRadius = (castingLayer.geometry.roundedCornersRadius.x +
448 castingLayer.geometry.roundedCornersRadius.y) /
449 2.0;
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800450 if (casterCornerRadius > 0.0f) {
451 // ignore the corners if a corner radius is set
452 Rect cornerRect(casterCornerRadius, casterCornerRadius);
453 casterRegion.subtractSelf(cornerRect.offsetTo(casterRect.left, casterRect.top));
454 casterRegion.subtractSelf(
455 cornerRect.offsetTo(casterRect.right - casterCornerRadius, casterRect.top));
456 casterRegion.subtractSelf(
457 cornerRect.offsetTo(casterRect.left, casterRect.bottom - casterCornerRadius));
458 casterRegion.subtractSelf(cornerRect.offsetTo(casterRect.right - casterCornerRadius,
459 casterRect.bottom - casterCornerRadius));
460 }
461
462 const float shadowInset = shadow.length * -1.0f;
463 const Rect casterWithShadow =
464 Rect(casterRect).inset(shadowInset, shadowInset, shadowInset, shadowInset);
465 const Region shadowRegion = Region(casterWithShadow).subtractSelf(casterRect);
466 const Region backgroundRegion = Region(fullscreenRect()).subtractSelf(casterWithShadow);
467
468 // verify casting layer
469 expectBufferColor(casterRegion, casterColor.r, casterColor.g, casterColor.b, casterColor.a);
470
471 // verify shadows by testing just the alpha since its difficult to validate the shadow color
472 size_t c;
473 Rect const* r = shadowRegion.getArray(&c);
474 for (size_t i = 0; i < c; i++, r++) {
475 expectAlpha(*r, 255);
476 }
477
478 // verify background
479 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
480 backgroundColor.a);
481 }
482
Alec Mouribd17b3b2020-12-17 11:08:30 -0800483 void expectShadowColorWithoutCaster(const FloatRect& casterBounds,
484 const renderengine::ShadowSettings& shadow,
485 const ubyte4& backgroundColor) {
486 const float shadowInset = shadow.length * -1.0f;
487 const Rect casterRect(casterBounds);
488 const Rect shadowRect =
489 Rect(casterRect).inset(shadowInset, shadowInset, shadowInset, shadowInset);
490
491 const Region backgroundRegion =
492 Region(fullscreenRect()).subtractSelf(casterRect).subtractSelf(shadowRect);
493
494 expectAlpha(shadowRect, 255);
495 // (0, 0, 0) fill on the bounds of the layer should be ignored.
496 expectBufferColor(casterRect, 255, 255, 255, 255, 254);
497
498 // verify background
499 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
500 backgroundColor.a);
501 }
502
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800503 static renderengine::ShadowSettings getShadowSettings(const vec2& casterPos, float shadowLength,
504 bool casterIsTranslucent) {
505 renderengine::ShadowSettings shadow;
506 shadow.ambientColor = {0.0f, 0.0f, 0.0f, 0.039f};
507 shadow.spotColor = {0.0f, 0.0f, 0.0f, 0.19f};
508 shadow.lightPos = vec3(casterPos.x, casterPos.y, 0);
509 shadow.lightRadius = 0.0f;
510 shadow.length = shadowLength;
511 shadow.casterIsTranslucent = casterIsTranslucent;
512 return shadow;
513 }
514
Alec Mouri1089aed2018-10-25 21:33:57 -0700515 static Rect fullscreenRect() { return Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT); }
516
517 static Rect offsetRect() {
518 return Rect(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_WIDTH,
519 DEFAULT_DISPLAY_HEIGHT);
520 }
521
522 static Rect offsetRectAtZero() {
523 return Rect(DEFAULT_DISPLAY_WIDTH - DEFAULT_DISPLAY_OFFSET,
524 DEFAULT_DISPLAY_HEIGHT - DEFAULT_DISPLAY_OFFSET);
525 }
526
Sally Qi59a9f502021-10-12 18:53:23 +0000527 void invokeDraw(const renderengine::DisplaySettings& settings,
528 const std::vector<renderengine::LayerSettings>& layers) {
Sally Qi4cabdd02021-08-05 16:45:57 -0700529 std::future<renderengine::RenderEngineResult> result =
530 mRE->drawLayers(settings, layers, mBuffer, true, base::unique_fd());
Sally Qi59a9f502021-10-12 18:53:23 +0000531
Sally Qi4cabdd02021-08-05 16:45:57 -0700532 ASSERT_TRUE(result.valid());
533 auto [status, fence] = result.get();
Alec Mouri1089aed2018-10-25 21:33:57 -0700534
Derek Sollenbergerec411212021-08-25 10:54:47 -0400535 ASSERT_EQ(NO_ERROR, status);
536 if (fence.ok()) {
537 sync_wait(fence.get(), -1);
Alec Mouri1089aed2018-10-25 21:33:57 -0700538 }
539
Alec Mouric0aae732021-01-12 13:32:18 -0800540 if (layers.size() > 0 && mGLESRE != nullptr) {
Alec Mouria90a5702021-04-16 16:36:21 +0000541 ASSERT_TRUE(mGLESRE->isFramebufferImageCachedForTesting(mBuffer->getBuffer()->getId()));
Alec Mourid43ccab2019-03-13 12:23:45 -0700542 }
Alec Mouri1089aed2018-10-25 21:33:57 -0700543 }
544
Alec Mourid43ccab2019-03-13 12:23:45 -0700545 void drawEmptyLayers() {
Alec Mouri6e57f682018-09-29 20:45:08 -0700546 renderengine::DisplaySettings settings;
Sally Qi59a9f502021-10-12 18:53:23 +0000547 std::vector<renderengine::LayerSettings> layers;
Alec Mouric0aae732021-01-12 13:32:18 -0800548 invokeDraw(settings, layers);
Alec Mouri6e57f682018-09-29 20:45:08 -0700549 }
550
Alec Mouri1089aed2018-10-25 21:33:57 -0700551 template <typename SourceVariant>
552 void fillBuffer(half r, half g, half b, half a);
553
554 template <typename SourceVariant>
555 void fillRedBuffer();
556
557 template <typename SourceVariant>
558 void fillGreenBuffer();
559
560 template <typename SourceVariant>
561 void fillBlueBuffer();
562
563 template <typename SourceVariant>
564 void fillRedTransparentBuffer();
565
566 template <typename SourceVariant>
567 void fillRedOffsetBuffer();
568
569 template <typename SourceVariant>
570 void fillBufferPhysicalOffset();
571
572 template <typename SourceVariant>
Alec Mouri5a6d8572020-03-23 23:56:15 -0700573 void fillBufferCheckers(uint32_t rotation);
Alec Mouri1089aed2018-10-25 21:33:57 -0700574
575 template <typename SourceVariant>
576 void fillBufferCheckersRotate0();
577
578 template <typename SourceVariant>
579 void fillBufferCheckersRotate90();
580
581 template <typename SourceVariant>
582 void fillBufferCheckersRotate180();
583
584 template <typename SourceVariant>
585 void fillBufferCheckersRotate270();
586
587 template <typename SourceVariant>
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800588 void fillBufferWithLayerTransform();
589
590 template <typename SourceVariant>
Alec Mouri1089aed2018-10-25 21:33:57 -0700591 void fillBufferLayerTransform();
592
593 template <typename SourceVariant>
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800594 void fillBufferWithColorTransform();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800595
596 template <typename SourceVariant>
Alec Mouri1089aed2018-10-25 21:33:57 -0700597 void fillBufferColorTransform();
598
Alec Mouri7c94edb2018-12-03 21:23:26 -0800599 template <typename SourceVariant>
Sally Qi2019fd22021-11-22 10:19:04 -0800600 void fillBufferWithColorTransformAndSourceDataspace(const ui::Dataspace sourceDataspace);
601
602 template <typename SourceVariant>
603 void fillBufferColorTransformAndSourceDataspace();
604
605 template <typename SourceVariant>
606 void fillBufferWithColorTransformAndOutputDataspace(const ui::Dataspace outputDataspace);
607
608 template <typename SourceVariant>
609 void fillBufferColorTransformAndOutputDataspace();
610
611 template <typename SourceVariant>
KaiChieh Chuangda2845c2020-12-14 16:49:38 +0800612 void fillBufferWithColorTransformZeroLayerAlpha();
613
614 template <typename SourceVariant>
615 void fillBufferColorTransformZeroLayerAlpha();
616
617 template <typename SourceVariant>
Alec Mouri7c94edb2018-12-03 21:23:26 -0800618 void fillRedBufferWithRoundedCorners();
619
620 template <typename SourceVariant>
621 void fillBufferWithRoundedCorners();
622
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000623 template <typename SourceVariant>
Lucas Dupin19c8f0e2019-11-25 17:55:44 -0800624 void fillBufferAndBlurBackground();
625
626 template <typename SourceVariant>
Alec Mourie8489fd2021-04-29 16:08:56 -0700627 void fillSmallLayerAndBlurBackground();
628
629 template <typename SourceVariant>
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000630 void overlayCorners();
631
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800632 void fillRedBufferTextureTransform();
633
634 void fillBufferTextureTransform();
635
636 void fillRedBufferWithPremultiplyAlpha();
637
638 void fillBufferWithPremultiplyAlpha();
639
640 void fillRedBufferWithoutPremultiplyAlpha();
641
642 void fillBufferWithoutPremultiplyAlpha();
643
Alec Mouriac335532018-11-12 15:01:33 -0800644 void fillGreenColorBufferThenClearRegion();
645
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800646 template <typename SourceVariant>
647 void drawShadow(const renderengine::LayerSettings& castingLayer,
648 const renderengine::ShadowSettings& shadow, const ubyte4& casterColor,
649 const ubyte4& backgroundColor);
650
Alec Mouribd17b3b2020-12-17 11:08:30 -0800651 void drawShadowWithoutCaster(const FloatRect& castingBounds,
652 const renderengine::ShadowSettings& shadow,
653 const ubyte4& backgroundColor);
654
Alec Mouri5a493722022-01-26 16:43:02 -0800655 // Tonemaps grey values from sourceDataspace -> Display P3 and checks that GPU and CPU
656 // implementations are identical Also implicitly checks that the injected tonemap shader
657 // compiles
658 void tonemap(ui::Dataspace sourceDataspace, std::function<vec3(vec3)> eotf,
659 std::function<vec3(vec3, float)> scaleOotf);
660
Alec Mouric0aae732021-01-12 13:32:18 -0800661 void initializeRenderEngine();
662
663 std::unique_ptr<renderengine::RenderEngine> mRE;
Alec Mouria90a5702021-04-16 16:36:21 +0000664 std::shared_ptr<renderengine::ExternalTexture> mBuffer;
Alec Mouric0aae732021-01-12 13:32:18 -0800665 // GLESRenderEngine for testing GLES-specific behavior.
666 // Owened by mRE, but this is downcasted.
667 renderengine::gl::GLESRenderEngine* mGLESRE = nullptr;
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800668
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800669 std::vector<uint32_t> mTexNames;
Alec Mouri6e57f682018-09-29 20:45:08 -0700670};
671
Alec Mouric0aae732021-01-12 13:32:18 -0800672void RenderEngineTest::initializeRenderEngine() {
673 const auto& renderEngineFactory = GetParam();
674 if (renderEngineFactory->type() == renderengine::RenderEngine::RenderEngineType::GLES) {
675 // Only GLESRenderEngine exposes test-only methods. Provide a pointer to the
676 // GLESRenderEngine if we're using it so that we don't need to dynamic_cast
677 // every time.
678 std::unique_ptr<renderengine::gl::GLESRenderEngine> renderEngine =
679 renderEngineFactory->createGLESRenderEngine();
680 mGLESRE = renderEngine.get();
681 mRE = std::move(renderEngine);
682 } else {
683 mRE = renderEngineFactory->createRenderEngine();
684 }
Alec Mouria90a5702021-04-16 16:36:21 +0000685 mBuffer = allocateDefaultBuffer();
Alec Mouric0aae732021-01-12 13:32:18 -0800686}
687
Alec Mouri1089aed2018-10-25 21:33:57 -0700688struct ColorSourceVariant {
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800689 static void fillColor(renderengine::LayerSettings& layer, half r, half g, half b,
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800690 RenderEngineTest* /*fixture*/) {
Alec Mouri1089aed2018-10-25 21:33:57 -0700691 layer.source.solidColor = half3(r, g, b);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800692 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700693 }
694};
695
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800696struct RelaxOpaqueBufferVariant {
697 static void setOpaqueBit(renderengine::LayerSettings& layer) {
698 layer.source.buffer.isOpaque = false;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800699 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800700 }
701
702 static uint8_t getAlphaChannel() { return 255; }
703};
704
705struct ForceOpaqueBufferVariant {
706 static void setOpaqueBit(renderengine::LayerSettings& layer) {
707 layer.source.buffer.isOpaque = true;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800708 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800709 }
710
711 static uint8_t getAlphaChannel() {
712 // The isOpaque bit will override the alpha channel, so this should be
713 // arbitrary.
Alec Mouric0aae732021-01-12 13:32:18 -0800714 return 50;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800715 }
716};
717
718template <typename OpaquenessVariant>
719struct BufferSourceVariant {
720 static void fillColor(renderengine::LayerSettings& layer, half r, half g, half b,
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800721 RenderEngineTest* fixture) {
Alec Mouria90a5702021-04-16 16:36:21 +0000722 const auto buf = fixture->allocateSourceBuffer(1, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800723 uint32_t texName;
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800724 fixture->mRE->genTextures(1, &texName);
725 fixture->mTexNames.push_back(texName);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800726
727 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +0000728 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
729 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800730
Alec Mouria90a5702021-04-16 16:36:21 +0000731 for (int32_t j = 0; j < buf->getBuffer()->getHeight(); j++) {
732 uint8_t* iter = pixels + (buf->getBuffer()->getStride() * j) * 4;
733 for (int32_t i = 0; i < buf->getBuffer()->getWidth(); i++) {
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800734 iter[0] = uint8_t(r * 255);
735 iter[1] = uint8_t(g * 255);
736 iter[2] = uint8_t(b * 255);
737 iter[3] = OpaquenessVariant::getAlphaChannel();
738 iter += 4;
739 }
740 }
741
Alec Mouria90a5702021-04-16 16:36:21 +0000742 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800743
744 layer.source.buffer.buffer = buf;
745 layer.source.buffer.textureName = texName;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800746 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800747 OpaquenessVariant::setOpaqueBit(layer);
748 }
749};
750
Alec Mouri1089aed2018-10-25 21:33:57 -0700751template <typename SourceVariant>
752void RenderEngineTest::fillBuffer(half r, half g, half b, half a) {
753 renderengine::DisplaySettings settings;
754 settings.physicalDisplay = fullscreenRect();
755 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800756 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700757
Sally Qi59a9f502021-10-12 18:53:23 +0000758 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700759
760 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800761 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700762 layer.geometry.boundaries = fullscreenRect().toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800763 SourceVariant::fillColor(layer, r, g, b, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700764 layer.alpha = a;
765
Sally Qi59a9f502021-10-12 18:53:23 +0000766 layers.push_back(layer);
Alec Mouri1089aed2018-10-25 21:33:57 -0700767
Alec Mouric0aae732021-01-12 13:32:18 -0800768 invokeDraw(settings, layers);
Alec Mouri1089aed2018-10-25 21:33:57 -0700769}
770
771template <typename SourceVariant>
772void RenderEngineTest::fillRedBuffer() {
773 fillBuffer<SourceVariant>(1.0f, 0.0f, 0.0f, 1.0f);
774 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
775}
776
777template <typename SourceVariant>
778void RenderEngineTest::fillGreenBuffer() {
779 fillBuffer<SourceVariant>(0.0f, 1.0f, 0.0f, 1.0f);
780 expectBufferColor(fullscreenRect(), 0, 255, 0, 255);
781}
782
783template <typename SourceVariant>
784void RenderEngineTest::fillBlueBuffer() {
785 fillBuffer<SourceVariant>(0.0f, 0.0f, 1.0f, 1.0f);
786 expectBufferColor(fullscreenRect(), 0, 0, 255, 255);
787}
788
789template <typename SourceVariant>
790void RenderEngineTest::fillRedTransparentBuffer() {
791 fillBuffer<SourceVariant>(1.0f, 0.0f, 0.0f, .2f);
792 expectBufferColor(fullscreenRect(), 51, 0, 0, 51);
793}
794
795template <typename SourceVariant>
796void RenderEngineTest::fillRedOffsetBuffer() {
797 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800798 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700799 settings.physicalDisplay = offsetRect();
800 settings.clip = offsetRectAtZero();
801
Sally Qi59a9f502021-10-12 18:53:23 +0000802 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700803
804 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800805 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700806 layer.geometry.boundaries = offsetRectAtZero().toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800807 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700808 layer.alpha = 1.0f;
809
Sally Qi59a9f502021-10-12 18:53:23 +0000810 layers.push_back(layer);
Alec Mouric0aae732021-01-12 13:32:18 -0800811 invokeDraw(settings, layers);
Alec Mouri1089aed2018-10-25 21:33:57 -0700812}
813
814template <typename SourceVariant>
815void RenderEngineTest::fillBufferPhysicalOffset() {
816 fillRedOffsetBuffer<SourceVariant>();
817
818 expectBufferColor(Rect(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_WIDTH,
819 DEFAULT_DISPLAY_HEIGHT),
820 255, 0, 0, 255);
821 Rect offsetRegionLeft(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_HEIGHT);
822 Rect offsetRegionTop(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_OFFSET);
823
824 expectBufferColor(offsetRegionLeft, 0, 0, 0, 0);
825 expectBufferColor(offsetRegionTop, 0, 0, 0, 0);
826}
827
828template <typename SourceVariant>
Alec Mouri5a6d8572020-03-23 23:56:15 -0700829void RenderEngineTest::fillBufferCheckers(uint32_t orientationFlag) {
Alec Mouri1089aed2018-10-25 21:33:57 -0700830 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800831 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700832 settings.physicalDisplay = fullscreenRect();
833 // Here logical space is 2x2
834 settings.clip = Rect(2, 2);
Alec Mouri5a6d8572020-03-23 23:56:15 -0700835 settings.orientation = orientationFlag;
Alec Mouri1089aed2018-10-25 21:33:57 -0700836
Sally Qi59a9f502021-10-12 18:53:23 +0000837 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700838
839 renderengine::LayerSettings layerOne;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800840 layerOne.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700841 Rect rectOne(0, 0, 1, 1);
842 layerOne.geometry.boundaries = rectOne.toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800843 SourceVariant::fillColor(layerOne, 1.0f, 0.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700844 layerOne.alpha = 1.0f;
845
846 renderengine::LayerSettings layerTwo;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800847 layerTwo.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700848 Rect rectTwo(0, 1, 1, 2);
849 layerTwo.geometry.boundaries = rectTwo.toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800850 SourceVariant::fillColor(layerTwo, 0.0f, 1.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700851 layerTwo.alpha = 1.0f;
852
853 renderengine::LayerSettings layerThree;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800854 layerThree.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700855 Rect rectThree(1, 0, 2, 1);
856 layerThree.geometry.boundaries = rectThree.toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800857 SourceVariant::fillColor(layerThree, 0.0f, 0.0f, 1.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700858 layerThree.alpha = 1.0f;
859
Sally Qi59a9f502021-10-12 18:53:23 +0000860 layers.push_back(layerOne);
861 layers.push_back(layerTwo);
862 layers.push_back(layerThree);
Alec Mouri1089aed2018-10-25 21:33:57 -0700863
Alec Mouric0aae732021-01-12 13:32:18 -0800864 invokeDraw(settings, layers);
Alec Mouri1089aed2018-10-25 21:33:57 -0700865}
866
867template <typename SourceVariant>
868void RenderEngineTest::fillBufferCheckersRotate0() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700869 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_0);
Alec Mouri1089aed2018-10-25 21:33:57 -0700870 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0,
871 255);
872 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
873 DEFAULT_DISPLAY_HEIGHT / 2),
874 0, 0, 255, 255);
875 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
876 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
877 0, 0, 0, 0);
878 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
879 DEFAULT_DISPLAY_HEIGHT),
880 0, 255, 0, 255);
881}
882
883template <typename SourceVariant>
884void RenderEngineTest::fillBufferCheckersRotate90() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700885 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_90);
Alec Mouri1089aed2018-10-25 21:33:57 -0700886 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 255, 0,
887 255);
888 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
889 DEFAULT_DISPLAY_HEIGHT / 2),
890 255, 0, 0, 255);
891 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
892 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
893 0, 0, 255, 255);
894 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
895 DEFAULT_DISPLAY_HEIGHT),
896 0, 0, 0, 0);
897}
898
899template <typename SourceVariant>
900void RenderEngineTest::fillBufferCheckersRotate180() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700901 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_180);
Alec Mouri1089aed2018-10-25 21:33:57 -0700902 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 0,
903 0);
904 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
905 DEFAULT_DISPLAY_HEIGHT / 2),
906 0, 255, 0, 255);
907 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
908 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
909 255, 0, 0, 255);
910 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
911 DEFAULT_DISPLAY_HEIGHT),
912 0, 0, 255, 255);
913}
914
915template <typename SourceVariant>
916void RenderEngineTest::fillBufferCheckersRotate270() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700917 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_270);
Alec Mouri1089aed2018-10-25 21:33:57 -0700918 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 255,
919 255);
920 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
921 DEFAULT_DISPLAY_HEIGHT / 2),
922 0, 0, 0, 0);
923 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
924 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
925 0, 255, 0, 255);
926 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
927 DEFAULT_DISPLAY_HEIGHT),
928 255, 0, 0, 255);
929}
930
931template <typename SourceVariant>
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800932void RenderEngineTest::fillBufferWithLayerTransform() {
Alec Mouri1089aed2018-10-25 21:33:57 -0700933 renderengine::DisplaySettings settings;
934 settings.physicalDisplay = fullscreenRect();
935 // Here logical space is 2x2
936 settings.clip = Rect(2, 2);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800937 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700938
Sally Qi59a9f502021-10-12 18:53:23 +0000939 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700940
941 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800942 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700943 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
944 // Translate one pixel diagonally
945 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 -0800946 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700947 layer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
948 layer.alpha = 1.0f;
949
Sally Qi59a9f502021-10-12 18:53:23 +0000950 layers.push_back(layer);
Alec Mouri1089aed2018-10-25 21:33:57 -0700951
Alec Mouric0aae732021-01-12 13:32:18 -0800952 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800953}
Alec Mouri1089aed2018-10-25 21:33:57 -0700954
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800955template <typename SourceVariant>
956void RenderEngineTest::fillBufferLayerTransform() {
957 fillBufferWithLayerTransform<SourceVariant>();
Alec Mouri1089aed2018-10-25 21:33:57 -0700958 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 0, 0);
959 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
960 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
961 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
962 255, 0, 0, 255);
963}
964
965template <typename SourceVariant>
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800966void RenderEngineTest::fillBufferWithColorTransform() {
Alec Mouri1089aed2018-10-25 21:33:57 -0700967 renderengine::DisplaySettings settings;
968 settings.physicalDisplay = fullscreenRect();
969 settings.clip = Rect(1, 1);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800970 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700971
Sally Qi59a9f502021-10-12 18:53:23 +0000972 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700973
974 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800975 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700976 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800977 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700978 layer.alpha = 1.0f;
979
980 // construct a fake color matrix
981 // annihilate green and blue channels
KaiChieh Chuang436fc192020-09-07 13:48:42 +0800982 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
Alec Mouri1089aed2018-10-25 21:33:57 -0700983 // set red channel to red + green
984 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
985
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800986 layer.alpha = 1.0f;
987 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
988
Sally Qi59a9f502021-10-12 18:53:23 +0000989 layers.push_back(layer);
Alec Mouri1089aed2018-10-25 21:33:57 -0700990
Alec Mouric0aae732021-01-12 13:32:18 -0800991 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800992}
Alec Mouri1089aed2018-10-25 21:33:57 -0700993
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800994template <typename SourceVariant>
Sally Qi2019fd22021-11-22 10:19:04 -0800995void RenderEngineTest::fillBufferWithColorTransformAndSourceDataspace(
996 const ui::Dataspace sourceDataspace) {
997 renderengine::DisplaySettings settings;
998 settings.physicalDisplay = fullscreenRect();
999 settings.clip = Rect(1, 1);
1000 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1001
1002 std::vector<renderengine::LayerSettings> layers;
1003
1004 renderengine::LayerSettings layer;
1005 layer.sourceDataspace = sourceDataspace;
1006 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1007 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
1008 layer.alpha = 1.0f;
1009
1010 // construct a fake color matrix
1011 // annihilate green and blue channels
1012 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
1013 // set red channel to red + green
1014 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
1015
1016 layer.alpha = 1.0f;
1017 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1018
1019 layers.push_back(layer);
1020
1021 invokeDraw(settings, layers);
1022}
1023
1024template <typename SourceVariant>
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001025void RenderEngineTest::fillBufferColorTransform() {
1026 fillBufferWithColorTransform<SourceVariant>();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08001027 expectBufferColor(fullscreenRect(), 172, 0, 0, 255, 1);
1028}
1029
1030template <typename SourceVariant>
Sally Qi2019fd22021-11-22 10:19:04 -08001031void RenderEngineTest::fillBufferColorTransformAndSourceDataspace() {
1032 unordered_map<ui::Dataspace, ubyte4> dataspaceToColorMap;
1033 dataspaceToColorMap[ui::Dataspace::V0_BT709] = {172, 0, 0, 255};
1034 dataspaceToColorMap[ui::Dataspace::BT2020] = {172, 0, 0, 255};
1035 dataspaceToColorMap[ui::Dataspace::ADOBE_RGB] = {172, 0, 0, 255};
1036 ui::Dataspace customizedDataspace = static_cast<ui::Dataspace>(
1037 ui::Dataspace::STANDARD_BT709 | ui::Dataspace::TRANSFER_GAMMA2_2 |
1038 ui::Dataspace::RANGE_FULL);
1039 dataspaceToColorMap[customizedDataspace] = {172, 0, 0, 255};
1040 for (const auto& [sourceDataspace, color] : dataspaceToColorMap) {
1041 fillBufferWithColorTransformAndSourceDataspace<SourceVariant>(sourceDataspace);
1042 expectBufferColor(fullscreenRect(), color.r, color.g, color.b, color.a, 1);
1043 }
1044}
1045
1046template <typename SourceVariant>
1047void RenderEngineTest::fillBufferWithColorTransformAndOutputDataspace(
1048 const ui::Dataspace outputDataspace) {
1049 renderengine::DisplaySettings settings;
1050 settings.physicalDisplay = fullscreenRect();
1051 settings.clip = Rect(1, 1);
1052 settings.outputDataspace = outputDataspace;
1053
1054 std::vector<renderengine::LayerSettings> layers;
1055
1056 renderengine::LayerSettings layer;
1057 layer.sourceDataspace = ui::Dataspace::V0_SCRGB_LINEAR;
1058 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1059 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
1060 layer.alpha = 1.0f;
1061
1062 // construct a fake color matrix
1063 // annihilate green and blue channels
1064 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
1065 // set red channel to red + green
1066 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
1067
1068 layer.alpha = 1.0f;
1069 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1070
1071 layers.push_back(layer);
1072
1073 invokeDraw(settings, layers);
1074}
1075
1076template <typename SourceVariant>
1077void RenderEngineTest::fillBufferColorTransformAndOutputDataspace() {
1078 unordered_map<ui::Dataspace, ubyte4> dataspaceToColorMap;
1079 dataspaceToColorMap[ui::Dataspace::V0_BT709] = {202, 0, 0, 255};
1080 dataspaceToColorMap[ui::Dataspace::BT2020] = {192, 0, 0, 255};
1081 dataspaceToColorMap[ui::Dataspace::ADOBE_RGB] = {202, 0, 0, 255};
1082 ui::Dataspace customizedDataspace = static_cast<ui::Dataspace>(
1083 ui::Dataspace::STANDARD_BT709 | ui::Dataspace::TRANSFER_GAMMA2_6 |
1084 ui::Dataspace::RANGE_FULL);
1085 dataspaceToColorMap[customizedDataspace] = {202, 0, 0, 255};
1086 for (const auto& [outputDataspace, color] : dataspaceToColorMap) {
1087 fillBufferWithColorTransformAndOutputDataspace<SourceVariant>(outputDataspace);
1088 expectBufferColor(fullscreenRect(), color.r, color.g, color.b, color.a, 1);
1089 }
1090}
1091
1092template <typename SourceVariant>
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001093void RenderEngineTest::fillBufferWithColorTransformZeroLayerAlpha() {
1094 renderengine::DisplaySettings settings;
1095 settings.physicalDisplay = fullscreenRect();
1096 settings.clip = Rect(1, 1);
1097
Sally Qi59a9f502021-10-12 18:53:23 +00001098 std::vector<renderengine::LayerSettings> layers;
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001099
1100 renderengine::LayerSettings layer;
1101 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1102 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
1103 layer.alpha = 0;
1104
1105 // construct a fake color matrix
1106 // simple inverse color
1107 settings.colorTransform = mat4(-1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 1, 1, 1, 1);
1108
1109 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1110
Sally Qi59a9f502021-10-12 18:53:23 +00001111 layers.push_back(layer);
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001112
Alec Mouric0aae732021-01-12 13:32:18 -08001113 invokeDraw(settings, layers);
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001114}
1115
1116template <typename SourceVariant>
1117void RenderEngineTest::fillBufferColorTransformZeroLayerAlpha() {
1118 fillBufferWithColorTransformZeroLayerAlpha<SourceVariant>();
1119 expectBufferColor(fullscreenRect(), 0, 0, 0, 0);
1120}
1121
1122template <typename SourceVariant>
Alec Mouri7c94edb2018-12-03 21:23:26 -08001123void RenderEngineTest::fillRedBufferWithRoundedCorners() {
1124 renderengine::DisplaySettings settings;
1125 settings.physicalDisplay = fullscreenRect();
1126 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001127 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri7c94edb2018-12-03 21:23:26 -08001128
Sally Qi59a9f502021-10-12 18:53:23 +00001129 std::vector<renderengine::LayerSettings> layers;
Alec Mouri7c94edb2018-12-03 21:23:26 -08001130
1131 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001132 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri7c94edb2018-12-03 21:23:26 -08001133 layer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07001134 layer.geometry.roundedCornersRadius = {5.0f, 5.0f};
Alec Mouri7c94edb2018-12-03 21:23:26 -08001135 layer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
1136 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
1137 layer.alpha = 1.0f;
1138
Sally Qi59a9f502021-10-12 18:53:23 +00001139 layers.push_back(layer);
Alec Mouri7c94edb2018-12-03 21:23:26 -08001140
Alec Mouric0aae732021-01-12 13:32:18 -08001141 invokeDraw(settings, layers);
Alec Mouri7c94edb2018-12-03 21:23:26 -08001142}
1143
1144template <typename SourceVariant>
1145void RenderEngineTest::fillBufferWithRoundedCorners() {
1146 fillRedBufferWithRoundedCorners<SourceVariant>();
1147 // Corners should be ignored...
1148 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 0);
1149 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, 0, DEFAULT_DISPLAY_WIDTH, 1), 0, 0, 0, 0);
1150 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT - 1, 1, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
1151 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1,
1152 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1153 0, 0, 0, 0);
1154 // ...And the non-rounded portion should be red.
1155 // Other pixels may be anti-aliased, so let's not check those.
1156 expectBufferColor(Rect(5, 5, DEFAULT_DISPLAY_WIDTH - 5, DEFAULT_DISPLAY_HEIGHT - 5), 255, 0, 0,
1157 255);
1158}
1159
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001160template <typename SourceVariant>
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001161void RenderEngineTest::fillBufferAndBlurBackground() {
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001162 auto blurRadius = 50;
1163 auto center = DEFAULT_DISPLAY_WIDTH / 2;
1164
1165 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001166 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001167 settings.physicalDisplay = fullscreenRect();
1168 settings.clip = fullscreenRect();
1169
Sally Qi59a9f502021-10-12 18:53:23 +00001170 std::vector<renderengine::LayerSettings> layers;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001171
1172 renderengine::LayerSettings backgroundLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001173 backgroundLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001174 backgroundLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1175 SourceVariant::fillColor(backgroundLayer, 0.0f, 1.0f, 0.0f, this);
1176 backgroundLayer.alpha = 1.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001177 layers.emplace_back(backgroundLayer);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001178
1179 renderengine::LayerSettings leftLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001180 leftLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001181 leftLayer.geometry.boundaries =
1182 Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT).toFloatRect();
1183 SourceVariant::fillColor(leftLayer, 1.0f, 0.0f, 0.0f, this);
1184 leftLayer.alpha = 1.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001185 layers.emplace_back(leftLayer);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001186
1187 renderengine::LayerSettings blurLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001188 blurLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001189 blurLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1190 blurLayer.backgroundBlurRadius = blurRadius;
Derek Sollenbergerecb21462021-01-29 16:53:49 -05001191 SourceVariant::fillColor(blurLayer, 0.0f, 0.0f, 1.0f, this);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001192 blurLayer.alpha = 0;
Sally Qi59a9f502021-10-12 18:53:23 +00001193 layers.emplace_back(blurLayer);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001194
Alec Mouric0aae732021-01-12 13:32:18 -08001195 invokeDraw(settings, layers);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001196
Derek Sollenbergerecb21462021-01-29 16:53:49 -05001197 // solid color
1198 expectBufferColor(Rect(0, 0, 1, 1), 255, 0, 0, 255, 0 /* tolerance */);
1199
Derek Sollenbergerb3998372021-02-16 15:16:56 -05001200 if (mRE->supportsBackgroundBlur()) {
1201 // blurred color (downsampling should result in the center color being close to 128)
1202 expectBufferColor(Rect(center - 1, center - 5, center + 1, center + 5), 128, 128, 0, 255,
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001203 50 /* tolerance */);
Derek Sollenbergerb3998372021-02-16 15:16:56 -05001204 }
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001205}
1206
1207template <typename SourceVariant>
Alec Mourie8489fd2021-04-29 16:08:56 -07001208void RenderEngineTest::fillSmallLayerAndBlurBackground() {
1209 auto blurRadius = 50;
1210 renderengine::DisplaySettings settings;
1211 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1212 settings.physicalDisplay = fullscreenRect();
1213 settings.clip = fullscreenRect();
1214
Sally Qi59a9f502021-10-12 18:53:23 +00001215 std::vector<renderengine::LayerSettings> layers;
Alec Mourie8489fd2021-04-29 16:08:56 -07001216
1217 renderengine::LayerSettings backgroundLayer;
1218 backgroundLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1219 backgroundLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1220 SourceVariant::fillColor(backgroundLayer, 1.0f, 0.0f, 0.0f, this);
1221 backgroundLayer.alpha = 1.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001222 layers.push_back(backgroundLayer);
Alec Mourie8489fd2021-04-29 16:08:56 -07001223
1224 renderengine::LayerSettings blurLayer;
1225 blurLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1226 blurLayer.geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f);
1227 blurLayer.backgroundBlurRadius = blurRadius;
1228 SourceVariant::fillColor(blurLayer, 0.0f, 0.0f, 1.0f, this);
1229 blurLayer.alpha = 0;
Sally Qi59a9f502021-10-12 18:53:23 +00001230 layers.push_back(blurLayer);
Alec Mourie8489fd2021-04-29 16:08:56 -07001231
1232 invokeDraw(settings, layers);
1233
1234 // Give a generous tolerance - the blur rectangle is very small and this test is
1235 // mainly concerned with ensuring that there's no device failure.
1236 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT), 255, 0, 0, 255,
1237 40 /* tolerance */);
1238}
1239
1240template <typename SourceVariant>
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001241void RenderEngineTest::overlayCorners() {
1242 renderengine::DisplaySettings settings;
1243 settings.physicalDisplay = fullscreenRect();
1244 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001245 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001246
Sally Qi59a9f502021-10-12 18:53:23 +00001247 std::vector<renderengine::LayerSettings> layersFirst;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001248
1249 renderengine::LayerSettings layerOne;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001250 layerOne.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001251 layerOne.geometry.boundaries =
1252 FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH / 3.0, DEFAULT_DISPLAY_HEIGHT / 3.0);
1253 SourceVariant::fillColor(layerOne, 1.0f, 0.0f, 0.0f, this);
1254 layerOne.alpha = 0.2;
1255
Sally Qi59a9f502021-10-12 18:53:23 +00001256 layersFirst.push_back(layerOne);
Alec Mouric0aae732021-01-12 13:32:18 -08001257 invokeDraw(settings, layersFirst);
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001258 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3), 51, 0, 0, 51);
1259 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3 + 1, DEFAULT_DISPLAY_HEIGHT / 3 + 1,
1260 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1261 0, 0, 0, 0);
1262
Sally Qi59a9f502021-10-12 18:53:23 +00001263 std::vector<renderengine::LayerSettings> layersSecond;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001264 renderengine::LayerSettings layerTwo;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001265 layerTwo.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001266 layerTwo.geometry.boundaries =
1267 FloatRect(DEFAULT_DISPLAY_WIDTH / 3.0, DEFAULT_DISPLAY_HEIGHT / 3.0,
1268 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT);
1269 SourceVariant::fillColor(layerTwo, 0.0f, 1.0f, 0.0f, this);
1270 layerTwo.alpha = 1.0f;
1271
Sally Qi59a9f502021-10-12 18:53:23 +00001272 layersSecond.push_back(layerTwo);
Alec Mouric0aae732021-01-12 13:32:18 -08001273 invokeDraw(settings, layersSecond);
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001274
1275 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3), 0, 0, 0, 0);
1276 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3 + 1, DEFAULT_DISPLAY_HEIGHT / 3 + 1,
1277 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1278 0, 255, 0, 255);
1279}
1280
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001281void RenderEngineTest::fillRedBufferTextureTransform() {
1282 renderengine::DisplaySettings settings;
1283 settings.physicalDisplay = fullscreenRect();
1284 settings.clip = Rect(1, 1);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001285 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001286
Sally Qi59a9f502021-10-12 18:53:23 +00001287 std::vector<renderengine::LayerSettings> layers;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001288
1289 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001290 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001291 // Here will allocate a checker board texture, but transform texture
1292 // coordinates so that only the upper left is applied.
Alec Mouria90a5702021-04-16 16:36:21 +00001293 const auto buf = allocateSourceBuffer(2, 2);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001294 uint32_t texName;
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001295 RenderEngineTest::mRE->genTextures(1, &texName);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001296 this->mTexNames.push_back(texName);
1297
1298 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00001299 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1300 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001301 // Red top left, Green top right, Blue bottom left, Black bottom right
1302 pixels[0] = 255;
1303 pixels[1] = 0;
1304 pixels[2] = 0;
1305 pixels[3] = 255;
1306 pixels[4] = 0;
1307 pixels[5] = 255;
1308 pixels[6] = 0;
1309 pixels[7] = 255;
1310 pixels[8] = 0;
1311 pixels[9] = 0;
1312 pixels[10] = 255;
1313 pixels[11] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00001314 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001315
1316 layer.source.buffer.buffer = buf;
1317 layer.source.buffer.textureName = texName;
1318 // Transform coordinates to only be inside the red quadrant.
Alec Mouri4049b532021-10-15 20:59:33 -07001319 layer.source.buffer.textureTransform = mat4::scale(vec4(0.2f, 0.2f, 1.f, 1.f));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001320 layer.alpha = 1.0f;
1321 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1322
Sally Qi59a9f502021-10-12 18:53:23 +00001323 layers.push_back(layer);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001324
Alec Mouric0aae732021-01-12 13:32:18 -08001325 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001326}
1327
1328void RenderEngineTest::fillBufferTextureTransform() {
1329 fillRedBufferTextureTransform();
1330 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
1331}
1332
1333void RenderEngineTest::fillRedBufferWithPremultiplyAlpha() {
1334 renderengine::DisplaySettings settings;
1335 settings.physicalDisplay = fullscreenRect();
1336 // Here logical space is 1x1
1337 settings.clip = Rect(1, 1);
1338
Sally Qi59a9f502021-10-12 18:53:23 +00001339 std::vector<renderengine::LayerSettings> layers;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001340
1341 renderengine::LayerSettings layer;
Alec Mouria90a5702021-04-16 16:36:21 +00001342 const auto buf = allocateSourceBuffer(1, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001343 uint32_t texName;
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001344 RenderEngineTest::mRE->genTextures(1, &texName);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001345 this->mTexNames.push_back(texName);
1346
1347 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00001348 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1349 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001350 pixels[0] = 255;
1351 pixels[1] = 0;
1352 pixels[2] = 0;
1353 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00001354 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001355
1356 layer.source.buffer.buffer = buf;
1357 layer.source.buffer.textureName = texName;
1358 layer.source.buffer.usePremultipliedAlpha = true;
1359 layer.alpha = 0.5f;
1360 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1361
Sally Qi59a9f502021-10-12 18:53:23 +00001362 layers.push_back(layer);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001363
Alec Mouric0aae732021-01-12 13:32:18 -08001364 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001365}
1366
1367void RenderEngineTest::fillBufferWithPremultiplyAlpha() {
1368 fillRedBufferWithPremultiplyAlpha();
1369 expectBufferColor(fullscreenRect(), 128, 0, 0, 128);
1370}
1371
1372void RenderEngineTest::fillRedBufferWithoutPremultiplyAlpha() {
1373 renderengine::DisplaySettings settings;
1374 settings.physicalDisplay = fullscreenRect();
1375 // Here logical space is 1x1
1376 settings.clip = Rect(1, 1);
1377
Sally Qi59a9f502021-10-12 18:53:23 +00001378 std::vector<renderengine::LayerSettings> layers;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001379
1380 renderengine::LayerSettings layer;
Alec Mouria90a5702021-04-16 16:36:21 +00001381 const auto buf = allocateSourceBuffer(1, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001382 uint32_t texName;
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001383 RenderEngineTest::mRE->genTextures(1, &texName);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001384 this->mTexNames.push_back(texName);
1385
1386 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00001387 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1388 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001389 pixels[0] = 255;
1390 pixels[1] = 0;
1391 pixels[2] = 0;
1392 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00001393 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001394
1395 layer.source.buffer.buffer = buf;
1396 layer.source.buffer.textureName = texName;
1397 layer.source.buffer.usePremultipliedAlpha = false;
1398 layer.alpha = 0.5f;
1399 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1400
Sally Qi59a9f502021-10-12 18:53:23 +00001401 layers.push_back(layer);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001402
Alec Mouric0aae732021-01-12 13:32:18 -08001403 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001404}
1405
1406void RenderEngineTest::fillBufferWithoutPremultiplyAlpha() {
1407 fillRedBufferWithoutPremultiplyAlpha();
wukui16f3c0bb2020-08-05 20:35:29 +08001408 expectBufferColor(fullscreenRect(), 128, 0, 0, 128, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001409}
1410
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001411template <typename SourceVariant>
1412void RenderEngineTest::drawShadow(const renderengine::LayerSettings& castingLayer,
1413 const renderengine::ShadowSettings& shadow,
1414 const ubyte4& casterColor, const ubyte4& backgroundColor) {
1415 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001416 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001417 settings.physicalDisplay = fullscreenRect();
1418 settings.clip = fullscreenRect();
1419
Sally Qi59a9f502021-10-12 18:53:23 +00001420 std::vector<renderengine::LayerSettings> layers;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001421
1422 // add background layer
1423 renderengine::LayerSettings bgLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001424 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001425 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1426 ColorSourceVariant::fillColor(bgLayer, backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1427 backgroundColor.b / 255.0f, this);
1428 bgLayer.alpha = backgroundColor.a / 255.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001429 layers.push_back(bgLayer);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001430
1431 // add shadow layer
1432 renderengine::LayerSettings shadowLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001433 shadowLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001434 shadowLayer.geometry.boundaries = castingLayer.geometry.boundaries;
1435 shadowLayer.alpha = castingLayer.alpha;
1436 shadowLayer.shadow = shadow;
Sally Qi59a9f502021-10-12 18:53:23 +00001437 layers.push_back(shadowLayer);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001438
1439 // add layer casting the shadow
1440 renderengine::LayerSettings layer = castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001441 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001442 SourceVariant::fillColor(layer, casterColor.r / 255.0f, casterColor.g / 255.0f,
1443 casterColor.b / 255.0f, this);
Sally Qi59a9f502021-10-12 18:53:23 +00001444 layers.push_back(layer);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001445
Alec Mouric0aae732021-01-12 13:32:18 -08001446 invokeDraw(settings, layers);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001447}
1448
Alec Mouribd17b3b2020-12-17 11:08:30 -08001449void RenderEngineTest::drawShadowWithoutCaster(const FloatRect& castingBounds,
1450 const renderengine::ShadowSettings& shadow,
1451 const ubyte4& backgroundColor) {
1452 renderengine::DisplaySettings settings;
1453 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1454 settings.physicalDisplay = fullscreenRect();
1455 settings.clip = fullscreenRect();
1456
Sally Qi59a9f502021-10-12 18:53:23 +00001457 std::vector<renderengine::LayerSettings> layers;
Alec Mouribd17b3b2020-12-17 11:08:30 -08001458
1459 // add background layer
1460 renderengine::LayerSettings bgLayer;
1461 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1462 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1463 ColorSourceVariant::fillColor(bgLayer, backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1464 backgroundColor.b / 255.0f, this);
1465 bgLayer.alpha = backgroundColor.a / 255.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001466 layers.push_back(bgLayer);
Alec Mouribd17b3b2020-12-17 11:08:30 -08001467
1468 // add shadow layer
1469 renderengine::LayerSettings shadowLayer;
1470 shadowLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1471 shadowLayer.geometry.boundaries = castingBounds;
Derek Sollenbergerc31985e2021-05-18 16:38:17 -04001472 shadowLayer.skipContentDraw = true;
Alec Mouribd17b3b2020-12-17 11:08:30 -08001473 shadowLayer.alpha = 1.0f;
1474 ColorSourceVariant::fillColor(shadowLayer, 0, 0, 0, this);
1475 shadowLayer.shadow = shadow;
Sally Qi59a9f502021-10-12 18:53:23 +00001476 layers.push_back(shadowLayer);
Alec Mouribd17b3b2020-12-17 11:08:30 -08001477
Alec Mouric0aae732021-01-12 13:32:18 -08001478 invokeDraw(settings, layers);
Alec Mouribd17b3b2020-12-17 11:08:30 -08001479}
1480
Alec Mouri5a493722022-01-26 16:43:02 -08001481void RenderEngineTest::tonemap(ui::Dataspace sourceDataspace, std::function<vec3(vec3)> eotf,
1482 std::function<vec3(vec3, float)> scaleOotf) {
1483 constexpr int32_t kGreyLevels = 256;
1484
1485 const auto rect = Rect(0, 0, kGreyLevels, 1);
1486
1487 constexpr float kMaxLuminance = 750.f;
1488 constexpr float kCurrentLuminanceNits = 500.f;
1489 const renderengine::DisplaySettings display{
1490 .physicalDisplay = rect,
1491 .clip = rect,
1492 .maxLuminance = kMaxLuminance,
1493 .currentLuminanceNits = kCurrentLuminanceNits,
1494 .outputDataspace = ui::Dataspace::DISPLAY_P3,
1495 };
1496
1497 auto buf = std::make_shared<
1498 renderengine::impl::
1499 ExternalTexture>(new GraphicBuffer(kGreyLevels, 1, HAL_PIXEL_FORMAT_RGBA_8888,
1500 1,
1501 GRALLOC_USAGE_SW_READ_OFTEN |
1502 GRALLOC_USAGE_SW_WRITE_OFTEN |
1503 GRALLOC_USAGE_HW_RENDER |
1504 GRALLOC_USAGE_HW_TEXTURE,
1505 "input"),
1506 *mRE,
1507 renderengine::impl::ExternalTexture::Usage::READABLE |
1508 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
1509 ASSERT_EQ(0, buf->getBuffer()->initCheck());
1510 {
1511 uint8_t* pixels;
1512 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1513 reinterpret_cast<void**>(&pixels));
1514
1515 uint8_t color = 0;
1516 for (int32_t j = 0; j < buf->getBuffer()->getHeight(); j++) {
1517 uint8_t* dest = pixels + (buf->getBuffer()->getStride() * j * 4);
1518 for (int32_t i = 0; i < buf->getBuffer()->getWidth(); i++) {
1519 dest[0] = color;
1520 dest[1] = color;
1521 dest[2] = color;
1522 dest[3] = 255;
1523 color++;
1524 dest += 4;
1525 }
1526 }
1527 buf->getBuffer()->unlock();
1528 }
1529
1530 mBuffer = std::make_shared<
1531 renderengine::impl::
1532 ExternalTexture>(new GraphicBuffer(kGreyLevels, 1, HAL_PIXEL_FORMAT_RGBA_8888,
1533 1,
1534 GRALLOC_USAGE_SW_READ_OFTEN |
1535 GRALLOC_USAGE_SW_WRITE_OFTEN |
1536 GRALLOC_USAGE_HW_RENDER |
1537 GRALLOC_USAGE_HW_TEXTURE,
1538 "output"),
1539 *mRE,
1540 renderengine::impl::ExternalTexture::Usage::READABLE |
1541 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
1542 ASSERT_EQ(0, mBuffer->getBuffer()->initCheck());
1543
1544 const renderengine::LayerSettings layer{.geometry.boundaries = rect.toFloatRect(),
1545 .source =
1546 renderengine::PixelSource{
1547 .buffer =
1548 renderengine::Buffer{
1549 .buffer =
1550 std::move(buf),
1551 .usePremultipliedAlpha =
1552 true,
1553 },
1554 },
1555 .alpha = 1.0f,
1556 .sourceDataspace = sourceDataspace};
1557
1558 std::vector<renderengine::LayerSettings> layers{layer};
1559 invokeDraw(display, layers);
1560
1561 ColorSpace displayP3 = ColorSpace::DisplayP3();
1562 ColorSpace bt2020 = ColorSpace::BT2020();
1563
1564 tonemap::Metadata metadata{.displayMaxLuminance = 750.0f};
1565
1566 auto generator = [=](Point location) {
1567 const double normColor = static_cast<double>(location.x) / (kGreyLevels - 1);
1568 const vec3 rgb = vec3(normColor, normColor, normColor);
1569
1570 const vec3 linearRGB = eotf(rgb);
1571
1572 const vec3 xyz = bt2020.getRGBtoXYZ() * linearRGB;
1573
1574 const vec3 scaledXYZ = scaleOotf(xyz, kCurrentLuminanceNits);
Alec Mouri196b0f22022-03-04 22:13:48 +00001575 const auto gains =
Alec Mouri5a493722022-01-26 16:43:02 -08001576 tonemap::getToneMapper()
1577 ->lookupTonemapGain(static_cast<aidl::android::hardware::graphics::common::
1578 Dataspace>(sourceDataspace),
1579 static_cast<aidl::android::hardware::graphics::common::
1580 Dataspace>(
1581 ui::Dataspace::DISPLAY_P3),
Alec Mouri196b0f22022-03-04 22:13:48 +00001582 {tonemap::
1583 Color{.linearRGB =
1584 scaleOotf(linearRGB,
1585 kCurrentLuminanceNits),
1586 .xyz = scaledXYZ}},
Alec Mouri5a493722022-01-26 16:43:02 -08001587 metadata);
Alec Mouri196b0f22022-03-04 22:13:48 +00001588 EXPECT_EQ(1, gains.size());
1589 const double gain = gains.front();
Alec Mouri5a493722022-01-26 16:43:02 -08001590 const vec3 normalizedXYZ = scaledXYZ * gain / metadata.displayMaxLuminance;
1591
1592 const vec3 targetRGB = OETF_sRGB(displayP3.getXYZtoRGB() * normalizedXYZ) * 255;
1593 return ubyte4(static_cast<uint8_t>(targetRGB.r), static_cast<uint8_t>(targetRGB.g),
1594 static_cast<uint8_t>(targetRGB.b), 255);
1595 };
1596
1597 expectBufferColor(Rect(kGreyLevels, 1), generator, 2);
1598}
1599
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001600INSTANTIATE_TEST_SUITE_P(PerRenderEngineType, RenderEngineTest,
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001601 testing::Values(std::make_shared<GLESRenderEngineFactory>(),
Alec Mouri0eab3e82020-12-08 18:10:27 -08001602 std::make_shared<GLESCMRenderEngineFactory>(),
1603 std::make_shared<SkiaGLESRenderEngineFactory>(),
1604 std::make_shared<SkiaGLESCMRenderEngineFactory>()));
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001605
1606TEST_P(RenderEngineTest, drawLayers_noLayersToDraw) {
Alec Mouric0aae732021-01-12 13:32:18 -08001607 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001608 drawEmptyLayers();
1609}
1610
Sally Qi1fed86e2022-06-23 15:33:52 -07001611TEST_P(RenderEngineTest, drawLayers_fillRedBufferAndEmptyBuffer) {
1612 const auto& renderEngineFactory = GetParam();
1613 if (renderEngineFactory->type() == renderengine::RenderEngine::RenderEngineType::GLES) {
1614 // GLES-specific test
1615 return;
1616 }
1617
1618 initializeRenderEngine();
1619 renderengine::DisplaySettings settings;
1620 settings.physicalDisplay = fullscreenRect();
1621 settings.clip = fullscreenRect();
1622 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1623
1624 // add a red layer
1625 renderengine::LayerSettings layerOne{
1626 .geometry.boundaries = fullscreenRect().toFloatRect(),
1627 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
1628 .alpha = 1.f,
1629 };
1630
1631 std::vector<renderengine::LayerSettings> layersFirst{layerOne};
1632 invokeDraw(settings, layersFirst);
1633 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
1634
1635 // re-draw with an empty layer above it, and we get a transparent black one
1636 std::vector<renderengine::LayerSettings> layersSecond;
1637 invokeDraw(settings, layersSecond);
1638 expectBufferColor(fullscreenRect(), 0, 0, 0, 0);
1639}
1640
Ana Krulec07b98df2021-01-07 14:38:40 -08001641TEST_P(RenderEngineTest, drawLayers_withoutBuffers_withColorTransform) {
Alec Mouria90a5702021-04-16 16:36:21 +00001642 initializeRenderEngine();
Ana Krulec07b98df2021-01-07 14:38:40 -08001643
1644 renderengine::DisplaySettings settings;
1645 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1646 settings.physicalDisplay = fullscreenRect();
1647 settings.clip = fullscreenRect();
1648
1649 // 255, 255, 255, 255 is full opaque white.
Alec Mouri4049b532021-10-15 20:59:33 -07001650 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
1651 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Ana Krulec07b98df2021-01-07 14:38:40 -08001652 // Create layer with given color.
1653 renderengine::LayerSettings bgLayer;
1654 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1655 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1656 bgLayer.source.solidColor = half3(backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1657 backgroundColor.b / 255.0f);
1658 bgLayer.alpha = backgroundColor.a / 255.0f;
1659 // Transform the red color.
1660 bgLayer.colorTransform = mat4(-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
1661
Sally Qi59a9f502021-10-12 18:53:23 +00001662 std::vector<renderengine::LayerSettings> layers;
1663 layers.push_back(bgLayer);
Ana Krulec07b98df2021-01-07 14:38:40 -08001664
Alec Mouric0aae732021-01-12 13:32:18 -08001665 invokeDraw(settings, layers);
Ana Krulec07b98df2021-01-07 14:38:40 -08001666
1667 // Expect to see full opaque pixel (with inverted red from the transform).
Alec Mouric0aae732021-01-12 13:32:18 -08001668 expectBufferColor(Rect(0, 0, 10, 10), 0.f, backgroundColor.g, backgroundColor.b,
Ana Krulec07b98df2021-01-07 14:38:40 -08001669 backgroundColor.a);
1670}
1671
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001672TEST_P(RenderEngineTest, drawLayers_nullOutputBuffer) {
Alec Mouric0aae732021-01-12 13:32:18 -08001673 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001674
Alec Mourid43ccab2019-03-13 12:23:45 -07001675 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001676 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Sally Qi59a9f502021-10-12 18:53:23 +00001677 std::vector<renderengine::LayerSettings> layers;
Alec Mourid43ccab2019-03-13 12:23:45 -07001678 renderengine::LayerSettings layer;
1679 layer.geometry.boundaries = fullscreenRect().toFloatRect();
1680 BufferSourceVariant<ForceOpaqueBufferVariant>::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
Sally Qi59a9f502021-10-12 18:53:23 +00001681 layers.push_back(layer);
Sally Qi4cabdd02021-08-05 16:45:57 -07001682 std::future<renderengine::RenderEngineResult> result =
1683 mRE->drawLayers(settings, layers, nullptr, true, base::unique_fd());
Alec Mourid43ccab2019-03-13 12:23:45 -07001684
Sally Qi4cabdd02021-08-05 16:45:57 -07001685 ASSERT_TRUE(result.valid());
Derek Sollenbergerec411212021-08-25 10:54:47 -04001686 auto [status, fence] = result.get();
Alec Mourid43ccab2019-03-13 12:23:45 -07001687 ASSERT_EQ(BAD_VALUE, status);
Derek Sollenbergerec411212021-08-25 10:54:47 -04001688 ASSERT_FALSE(fence.ok());
Alec Mourid43ccab2019-03-13 12:23:45 -07001689}
1690
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001691TEST_P(RenderEngineTest, drawLayers_doesNotCacheFramebuffer) {
1692 const auto& renderEngineFactory = GetParam();
Alec Mouric0aae732021-01-12 13:32:18 -08001693
1694 if (renderEngineFactory->type() != renderengine::RenderEngine::RenderEngineType::GLES) {
1695 // GLES-specific test
1696 return;
1697 }
1698
1699 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001700
Alec Mourife0d72b2019-03-21 14:05:56 -07001701 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001702 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourife0d72b2019-03-21 14:05:56 -07001703 settings.physicalDisplay = fullscreenRect();
1704 settings.clip = fullscreenRect();
1705
Sally Qi59a9f502021-10-12 18:53:23 +00001706 std::vector<renderengine::LayerSettings> layers;
Alec Mourife0d72b2019-03-21 14:05:56 -07001707 renderengine::LayerSettings layer;
1708 layer.geometry.boundaries = fullscreenRect().toFloatRect();
1709 BufferSourceVariant<ForceOpaqueBufferVariant>::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
1710 layer.alpha = 1.0;
Sally Qi59a9f502021-10-12 18:53:23 +00001711 layers.push_back(layer);
Alec Mourife0d72b2019-03-21 14:05:56 -07001712
Sally Qi4cabdd02021-08-05 16:45:57 -07001713 std::future<renderengine::RenderEngineResult> result =
1714 mRE->drawLayers(settings, layers, mBuffer, false, base::unique_fd());
1715 ASSERT_TRUE(result.valid());
Derek Sollenbergerec411212021-08-25 10:54:47 -04001716 auto [status, fence] = result.get();
1717
Alec Mourife0d72b2019-03-21 14:05:56 -07001718 ASSERT_EQ(NO_ERROR, status);
Derek Sollenbergerec411212021-08-25 10:54:47 -04001719 if (fence.ok()) {
1720 sync_wait(fence.get(), -1);
1721 }
1722
Alec Mouria90a5702021-04-16 16:36:21 +00001723 ASSERT_FALSE(mGLESRE->isFramebufferImageCachedForTesting(mBuffer->getBuffer()->getId()));
Alec Mourife0d72b2019-03-21 14:05:56 -07001724 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
1725}
1726
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001727TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001728 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001729 fillRedBuffer<ColorSourceVariant>();
1730}
1731
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001732TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001733 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001734 fillGreenBuffer<ColorSourceVariant>();
1735}
1736
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001737TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001738 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001739 fillBlueBuffer<ColorSourceVariant>();
1740}
1741
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001742TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001743 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001744 fillRedTransparentBuffer<ColorSourceVariant>();
1745}
1746
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001747TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001748 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001749 fillBufferPhysicalOffset<ColorSourceVariant>();
1750}
1751
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001752TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001753 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001754 fillBufferCheckersRotate0<ColorSourceVariant>();
1755}
1756
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001757TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001758 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001759 fillBufferCheckersRotate90<ColorSourceVariant>();
1760}
1761
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001762TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001763 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001764 fillBufferCheckersRotate180<ColorSourceVariant>();
1765}
1766
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001767TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001768 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001769 fillBufferCheckersRotate270<ColorSourceVariant>();
1770}
1771
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001772TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001773 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001774 fillBufferLayerTransform<ColorSourceVariant>();
1775}
1776
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001777TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001778 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08001779 fillBufferColorTransform<ColorSourceVariant>();
1780}
1781
Sally Qi2019fd22021-11-22 10:19:04 -08001782TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_sourceDataspace) {
1783 const auto& renderEngineFactory = GetParam();
1784 // skip for non color management
1785 if (!renderEngineFactory->useColorManagement()) {
1786 return;
1787 }
1788 // skip for GLESRenderEngine
1789 if (renderEngineFactory->type() != renderengine::RenderEngine::RenderEngineType::GLES) {
1790 return;
1791 }
1792
1793 initializeRenderEngine();
1794 fillBufferColorTransformAndSourceDataspace<ColorSourceVariant>();
1795}
1796
1797TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_outputDataspace) {
1798 const auto& renderEngineFactory = GetParam();
1799 // skip for non color management
1800 if (!renderEngineFactory->useColorManagement()) {
1801 return;
1802 }
1803 // skip for GLESRenderEngine
1804 if (renderEngineFactory->type() != renderengine::RenderEngine::RenderEngineType::GLES) {
1805 return;
1806 }
1807
1808 initializeRenderEngine();
1809 fillBufferColorTransformAndOutputDataspace<ColorSourceVariant>();
1810}
1811
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001812TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001813 initializeRenderEngine();
Alec Mouri7c94edb2018-12-03 21:23:26 -08001814 fillBufferWithRoundedCorners<ColorSourceVariant>();
1815}
1816
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001817TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001818 initializeRenderEngine();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001819 fillBufferColorTransformZeroLayerAlpha<ColorSourceVariant>();
1820}
1821
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001822TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001823 initializeRenderEngine();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001824 fillBufferAndBlurBackground<ColorSourceVariant>();
1825}
1826
Alec Mourie8489fd2021-04-29 16:08:56 -07001827TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_colorSource) {
1828 initializeRenderEngine();
1829 fillSmallLayerAndBlurBackground<ColorSourceVariant>();
1830}
1831
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001832TEST_P(RenderEngineTest, drawLayers_overlayCorners_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001833 initializeRenderEngine();
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001834 overlayCorners<ColorSourceVariant>();
1835}
1836
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001837TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001838 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001839 fillRedBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1840}
1841
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001842TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001843 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001844 fillGreenBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1845}
1846
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001847TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001848 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001849 fillBlueBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1850}
1851
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001852TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001853 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001854 fillRedTransparentBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1855}
1856
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001857TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001858 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001859 fillBufferPhysicalOffset<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1860}
1861
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001862TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001863 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001864 fillBufferCheckersRotate0<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1865}
1866
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001867TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001868 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001869 fillBufferCheckersRotate90<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1870}
1871
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001872TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001873 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001874 fillBufferCheckersRotate180<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1875}
1876
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001877TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001878 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001879 fillBufferCheckersRotate270<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1880}
1881
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001882TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001883 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001884 fillBufferLayerTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1885}
1886
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001887TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001888 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08001889 fillBufferColorTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1890}
1891
Sally Qi2019fd22021-11-22 10:19:04 -08001892TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndSourceDataspace_opaqueBufferSource) {
1893 const auto& renderEngineFactory = GetParam();
1894 // skip for non color management
1895 if (!renderEngineFactory->useColorManagement()) {
1896 return;
1897 }
1898 // skip for GLESRenderEngine
1899 if (renderEngineFactory->type() != renderengine::RenderEngine::RenderEngineType::GLES) {
1900 return;
1901 }
1902
1903 initializeRenderEngine();
1904 fillBufferColorTransformAndSourceDataspace<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1905}
1906
1907TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndOutputDataspace_opaqueBufferSource) {
1908 const auto& renderEngineFactory = GetParam();
1909 // skip for non color management
1910 if (!renderEngineFactory->useColorManagement()) {
1911 return;
1912 }
1913 // skip for GLESRenderEngine
1914 if (renderEngineFactory->type() != renderengine::RenderEngine::RenderEngineType::GLES) {
1915 return;
1916 }
1917
1918 initializeRenderEngine();
1919 fillBufferColorTransformAndOutputDataspace<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1920}
1921
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001922TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001923 initializeRenderEngine();
Alec Mouri7c94edb2018-12-03 21:23:26 -08001924 fillBufferWithRoundedCorners<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1925}
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001926
Alec Mouric0aae732021-01-12 13:32:18 -08001927TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_opaqueBufferSource) {
1928 initializeRenderEngine();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001929 fillBufferColorTransformZeroLayerAlpha<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1930}
Alec Mouri7c94edb2018-12-03 21:23:26 -08001931
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001932TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001933 initializeRenderEngine();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001934 fillBufferAndBlurBackground<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1935}
1936
Alec Mourie8489fd2021-04-29 16:08:56 -07001937TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_opaqueBufferSource) {
1938 initializeRenderEngine();
1939 fillSmallLayerAndBlurBackground<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1940}
1941
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001942TEST_P(RenderEngineTest, drawLayers_overlayCorners_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001943 initializeRenderEngine();
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001944 overlayCorners<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1945}
1946
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001947TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001948 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001949 fillRedBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1950}
1951
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001952TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001953 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001954 fillGreenBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1955}
1956
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001957TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001958 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001959 fillBlueBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1960}
1961
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001962TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001963 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001964 fillRedTransparentBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1965}
1966
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001967TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001968 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001969 fillBufferPhysicalOffset<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1970}
1971
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001972TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001973 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001974 fillBufferCheckersRotate0<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1975}
1976
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001977TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001978 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001979 fillBufferCheckersRotate90<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1980}
1981
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001982TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001983 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001984 fillBufferCheckersRotate180<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1985}
1986
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001987TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001988 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001989 fillBufferCheckersRotate270<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1990}
1991
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001992TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001993 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001994 fillBufferLayerTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1995}
1996
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001997TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001998 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08001999 fillBufferColorTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2000}
2001
Sally Qi2019fd22021-11-22 10:19:04 -08002002TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndSourceDataspace_bufferSource) {
2003 const auto& renderEngineFactory = GetParam();
2004 // skip for non color management
2005 if (!renderEngineFactory->useColorManagement()) {
2006 return;
2007 }
2008 // skip for GLESRenderEngine
2009 if (renderEngineFactory->type() != renderengine::RenderEngine::RenderEngineType::GLES) {
2010 return;
2011 }
2012
2013 initializeRenderEngine();
2014 fillBufferColorTransformAndSourceDataspace<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2015}
2016
2017TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndOutputDataspace_bufferSource) {
2018 const auto& renderEngineFactory = GetParam();
2019 // skip for non color management
2020 if (!renderEngineFactory->useColorManagement()) {
2021 return;
2022 }
2023 // skip for GLESRenderEngine
2024 if (renderEngineFactory->type() != renderengine::RenderEngine::RenderEngineType::GLES) {
2025 return;
2026 }
2027
2028 initializeRenderEngine();
2029 fillBufferColorTransformAndOutputDataspace<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2030}
2031
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002032TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08002033 initializeRenderEngine();
Alec Mouri7c94edb2018-12-03 21:23:26 -08002034 fillBufferWithRoundedCorners<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2035}
2036
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08002037TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08002038 initializeRenderEngine();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08002039 fillBufferColorTransformZeroLayerAlpha<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2040}
2041
Nathaniel Nifong53494f32021-04-30 14:05:39 -04002042TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08002043 initializeRenderEngine();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08002044 fillBufferAndBlurBackground<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2045}
2046
Alec Mourie8489fd2021-04-29 16:08:56 -07002047TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_bufferSource) {
2048 initializeRenderEngine();
2049 fillSmallLayerAndBlurBackground<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2050}
2051
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002052TEST_P(RenderEngineTest, drawLayers_overlayCorners_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08002053 initializeRenderEngine();
Alec Mourie7d1d4a2019-02-05 01:13:46 +00002054 overlayCorners<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2055}
2056
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002057TEST_P(RenderEngineTest, drawLayers_fillBufferTextureTransform) {
Alec Mouric0aae732021-01-12 13:32:18 -08002058 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002059 fillBufferTextureTransform();
2060}
2061
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002062TEST_P(RenderEngineTest, drawLayers_fillBuffer_premultipliesAlpha) {
Alec Mouric0aae732021-01-12 13:32:18 -08002063 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002064 fillBufferWithPremultiplyAlpha();
2065}
2066
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002067TEST_P(RenderEngineTest, drawLayers_fillBuffer_withoutPremultiplyingAlpha) {
Alec Mouric0aae732021-01-12 13:32:18 -08002068 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002069 fillBufferWithoutPremultiplyAlpha();
2070}
2071
Alec Mouribd17b3b2020-12-17 11:08:30 -08002072TEST_P(RenderEngineTest, drawLayers_fillShadow_castsWithoutCasterLayer) {
Alec Mouric0aae732021-01-12 13:32:18 -08002073 initializeRenderEngine();
Alec Mouribd17b3b2020-12-17 11:08:30 -08002074
Alec Mouri4049b532021-10-15 20:59:33 -07002075 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2076 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Alec Mouribd17b3b2020-12-17 11:08:30 -08002077 const float shadowLength = 5.0f;
2078 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2079 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2080 renderengine::ShadowSettings settings =
2081 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2082 false /* casterIsTranslucent */);
2083
2084 drawShadowWithoutCaster(casterBounds.toFloatRect(), settings, backgroundColor);
2085 expectShadowColorWithoutCaster(casterBounds.toFloatRect(), settings, backgroundColor);
2086}
2087
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002088TEST_P(RenderEngineTest, drawLayers_fillShadow_casterLayerMinSize) {
Alec Mouric0aae732021-01-12 13:32:18 -08002089 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002090
Alec Mouri4049b532021-10-15 20:59:33 -07002091 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2092 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2093 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2094 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002095 const float shadowLength = 5.0f;
2096 Rect casterBounds(1, 1);
2097 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2098 renderengine::LayerSettings castingLayer;
2099 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2100 castingLayer.alpha = 1.0f;
2101 renderengine::ShadowSettings settings =
2102 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2103 false /* casterIsTranslucent */);
2104
2105 drawShadow<ColorSourceVariant>(castingLayer, settings, casterColor, backgroundColor);
2106 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2107}
2108
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002109TEST_P(RenderEngineTest, drawLayers_fillShadow_casterColorLayer) {
Alec Mouric0aae732021-01-12 13:32:18 -08002110 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002111
Alec Mouri4049b532021-10-15 20:59:33 -07002112 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2113 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2114 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2115 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002116 const float shadowLength = 5.0f;
2117 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2118 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2119 renderengine::LayerSettings castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002120 castingLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002121 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2122 castingLayer.alpha = 1.0f;
2123 renderengine::ShadowSettings settings =
2124 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2125 false /* casterIsTranslucent */);
2126
2127 drawShadow<ColorSourceVariant>(castingLayer, settings, casterColor, backgroundColor);
2128 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2129}
2130
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002131TEST_P(RenderEngineTest, drawLayers_fillShadow_casterOpaqueBufferLayer) {
Alec Mouric0aae732021-01-12 13:32:18 -08002132 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002133
Alec Mouri4049b532021-10-15 20:59:33 -07002134 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2135 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2136 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2137 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002138 const float shadowLength = 5.0f;
2139 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2140 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2141 renderengine::LayerSettings castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002142 castingLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002143 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2144 castingLayer.alpha = 1.0f;
2145 renderengine::ShadowSettings settings =
2146 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2147 false /* casterIsTranslucent */);
2148
2149 drawShadow<BufferSourceVariant<ForceOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2150 backgroundColor);
2151 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2152}
2153
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002154TEST_P(RenderEngineTest, drawLayers_fillShadow_casterWithRoundedCorner) {
Alec Mouric0aae732021-01-12 13:32:18 -08002155 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002156
Alec Mouri4049b532021-10-15 20:59:33 -07002157 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2158 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2159 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2160 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002161 const float shadowLength = 5.0f;
2162 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2163 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2164 renderengine::LayerSettings castingLayer;
2165 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002166 castingLayer.geometry.roundedCornersRadius = {3.0f, 3.0f};
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002167 castingLayer.geometry.roundedCornersCrop = casterBounds.toFloatRect();
2168 castingLayer.alpha = 1.0f;
2169 renderengine::ShadowSettings settings =
2170 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2171 false /* casterIsTranslucent */);
2172
2173 drawShadow<BufferSourceVariant<ForceOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2174 backgroundColor);
2175 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2176}
2177
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002178TEST_P(RenderEngineTest, drawLayers_fillShadow_translucentCasterWithAlpha) {
Alec Mouric0aae732021-01-12 13:32:18 -08002179 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002180
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002181 const ubyte4 casterColor(255, 0, 0, 255);
2182 const ubyte4 backgroundColor(255, 255, 255, 255);
2183 const float shadowLength = 5.0f;
2184 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2185 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2186 renderengine::LayerSettings castingLayer;
2187 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2188 castingLayer.alpha = 0.5f;
2189 renderengine::ShadowSettings settings =
2190 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2191 true /* casterIsTranslucent */);
2192
2193 drawShadow<BufferSourceVariant<RelaxOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2194 backgroundColor);
2195
2196 // verify only the background since the shadow will draw behind the caster
2197 const float shadowInset = settings.length * -1.0f;
2198 const Rect casterWithShadow =
2199 Rect(casterBounds).inset(shadowInset, shadowInset, shadowInset, shadowInset);
2200 const Region backgroundRegion = Region(fullscreenRect()).subtractSelf(casterWithShadow);
2201 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
2202 backgroundColor.a);
2203}
2204
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002205TEST_P(RenderEngineTest, cleanupPostRender_cleansUpOnce) {
Alec Mouric0aae732021-01-12 13:32:18 -08002206 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002207
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002208 renderengine::DisplaySettings settings;
2209 settings.physicalDisplay = fullscreenRect();
2210 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002211 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002212
Sally Qi59a9f502021-10-12 18:53:23 +00002213 std::vector<renderengine::LayerSettings> layers;
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002214 renderengine::LayerSettings layer;
2215 layer.geometry.boundaries = fullscreenRect().toFloatRect();
2216 BufferSourceVariant<ForceOpaqueBufferVariant>::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
2217 layer.alpha = 1.0;
Sally Qi59a9f502021-10-12 18:53:23 +00002218 layers.push_back(layer);
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002219
Sally Qi4cabdd02021-08-05 16:45:57 -07002220 std::future<renderengine::RenderEngineResult> resultOne =
2221 mRE->drawLayers(settings, layers, mBuffer, true, base::unique_fd());
2222 ASSERT_TRUE(resultOne.valid());
2223 auto [statusOne, fenceOne] = resultOne.get();
2224 ASSERT_EQ(NO_ERROR, statusOne);
2225
2226 std::future<renderengine::RenderEngineResult> resultTwo =
2227 mRE->drawLayers(settings, layers, mBuffer, true, std::move(fenceOne));
2228 ASSERT_TRUE(resultTwo.valid());
2229 auto [statusTwo, fenceTwo] = resultTwo.get();
2230 ASSERT_EQ(NO_ERROR, statusTwo);
Derek Sollenbergerec411212021-08-25 10:54:47 -04002231 if (fenceTwo.ok()) {
2232 sync_wait(fenceTwo.get(), -1);
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002233 }
Derek Sollenbergerec411212021-08-25 10:54:47 -04002234
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002235 // Only cleanup the first time.
Derek Sollenbergerd3f60652021-06-11 15:34:36 -04002236 EXPECT_FALSE(mRE->canSkipPostRenderCleanup());
2237 mRE->cleanupPostRender();
2238 EXPECT_TRUE(mRE->canSkipPostRenderCleanup());
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002239}
2240
Ana Krulecf9a15d92020-12-11 08:35:00 -08002241TEST_P(RenderEngineTest, testRoundedCornersCrop) {
Alec Mouric0aae732021-01-12 13:32:18 -08002242 initializeRenderEngine();
Ana Krulecf9a15d92020-12-11 08:35:00 -08002243
2244 renderengine::DisplaySettings settings;
2245 settings.physicalDisplay = fullscreenRect();
2246 settings.clip = fullscreenRect();
2247 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2248
Sally Qi59a9f502021-10-12 18:53:23 +00002249 std::vector<renderengine::LayerSettings> layers;
Ana Krulecf9a15d92020-12-11 08:35:00 -08002250
2251 renderengine::LayerSettings redLayer;
2252 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2253 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002254 redLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
2255
Ana Krulecf9a15d92020-12-11 08:35:00 -08002256 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2257 // Red background.
2258 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2259 redLayer.alpha = 1.0f;
2260
Sally Qi59a9f502021-10-12 18:53:23 +00002261 layers.push_back(redLayer);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002262
2263 // Green layer with 1/3 size.
2264 renderengine::LayerSettings greenLayer;
2265 greenLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2266 greenLayer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002267 greenLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
Ana Krulecf9a15d92020-12-11 08:35:00 -08002268 // Bottom right corner is not going to be rounded.
2269 greenLayer.geometry.roundedCornersCrop =
2270 Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3, DEFAULT_DISPLAY_HEIGHT,
2271 DEFAULT_DISPLAY_HEIGHT)
2272 .toFloatRect();
2273 greenLayer.source.solidColor = half3(0.0f, 1.0f, 0.0f);
2274 greenLayer.alpha = 1.0f;
2275
Sally Qi59a9f502021-10-12 18:53:23 +00002276 layers.push_back(greenLayer);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002277
Alec Mouric0aae732021-01-12 13:32:18 -08002278 invokeDraw(settings, layers);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002279
2280 // Corners should be ignored...
2281 // Screen size: width is 128, height is 256.
2282 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 0);
2283 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, 0, DEFAULT_DISPLAY_WIDTH, 1), 0, 0, 0, 0);
2284 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT - 1, 1, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
2285 // Bottom right corner is kept out of the clipping, and it's green.
2286 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1,
2287 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
2288 0, 255, 0, 255);
2289}
2290
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002291TEST_P(RenderEngineTest, testRoundedCornersParentCrop) {
2292 initializeRenderEngine();
2293
2294 renderengine::DisplaySettings settings;
2295 settings.physicalDisplay = fullscreenRect();
2296 settings.clip = fullscreenRect();
2297 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2298
Sally Qi59a9f502021-10-12 18:53:23 +00002299 std::vector<renderengine::LayerSettings> layers;
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002300
2301 renderengine::LayerSettings redLayer;
2302 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2303 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002304 redLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002305 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2306 // Red background.
2307 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2308 redLayer.alpha = 1.0f;
2309
Sally Qi59a9f502021-10-12 18:53:23 +00002310 layers.push_back(redLayer);
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002311
2312 // Green layer with 1/2 size with parent crop rect.
2313 renderengine::LayerSettings greenLayer = redLayer;
2314 greenLayer.geometry.boundaries =
2315 FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT / 2);
2316 greenLayer.source.solidColor = half3(0.0f, 1.0f, 0.0f);
2317
Sally Qi59a9f502021-10-12 18:53:23 +00002318 layers.push_back(greenLayer);
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002319
2320 invokeDraw(settings, layers);
2321
2322 // Due to roundedCornersRadius, the corners are untouched.
2323 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2324 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2325 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2326 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2327
2328 // top middle should be green and the bottom middle red
2329 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, 0), 0, 255, 0, 255);
2330 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0, 255);
2331
2332 // the bottom edge of the green layer should not be rounded
2333 expectBufferColor(Point(0, (DEFAULT_DISPLAY_HEIGHT / 2) - 1), 0, 255, 0, 255);
2334}
2335
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002336TEST_P(RenderEngineTest, testRoundedCornersParentCropSmallBounds) {
2337 initializeRenderEngine();
2338
2339 renderengine::DisplaySettings settings;
2340 settings.physicalDisplay = fullscreenRect();
2341 settings.clip = fullscreenRect();
2342 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2343
Sally Qi59a9f502021-10-12 18:53:23 +00002344 std::vector<renderengine::LayerSettings> layers;
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002345
2346 renderengine::LayerSettings redLayer;
2347 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2348 redLayer.geometry.boundaries = FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, 32);
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002349 redLayer.geometry.roundedCornersRadius = {64.0f, 64.0f};
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002350 redLayer.geometry.roundedCornersCrop = FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, 128);
2351 // Red background.
2352 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2353 redLayer.alpha = 1.0f;
2354
Sally Qi59a9f502021-10-12 18:53:23 +00002355 layers.push_back(redLayer);
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002356 invokeDraw(settings, layers);
2357
2358 // Due to roundedCornersRadius, the top corners are untouched.
2359 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2360 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2361
2362 // ensure that the entire height of the red layer was clipped by the rounded corners crop.
2363 expectBufferColor(Point(0, 31), 0, 0, 0, 0);
2364 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 31), 0, 0, 0, 0);
2365
2366 // the bottom middle should be red
2367 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, 31), 255, 0, 0, 255);
2368}
2369
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002370TEST_P(RenderEngineTest, testRoundedCornersXY) {
2371 if (GetParam()->type() != renderengine::RenderEngine::RenderEngineType::SKIA_GL) {
2372 GTEST_SKIP();
2373 }
2374
2375 initializeRenderEngine();
2376
2377 renderengine::DisplaySettings settings;
2378 settings.physicalDisplay = fullscreenRect();
2379 settings.clip = fullscreenRect();
2380 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2381
2382 std::vector<renderengine::LayerSettings> layers;
2383
2384 renderengine::LayerSettings redLayer;
2385 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2386 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
2387 redLayer.geometry.roundedCornersRadius = {5.0f, 20.0f};
2388 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2389 // Red background.
2390 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2391 redLayer.alpha = 1.0f;
2392
2393 layers.push_back(redLayer);
2394
2395 invokeDraw(settings, layers);
2396
2397 // Due to roundedCornersRadius, the corners are untouched.
2398 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2399 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2400 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2401 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2402
2403 // Y-axis draws a larger radius, check that its untouched as well
2404 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 5), 0, 0, 0, 0);
2405 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 5), 0, 0, 0, 0);
2406 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 5), 0, 0, 0, 0);
2407 expectBufferColor(Point(0, 5), 0, 0, 0, 0);
2408
2409 // middle should be red
2410 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0, 255);
2411}
2412
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002413TEST_P(RenderEngineTest, testClear) {
2414 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) {
2443 initializeRenderEngine();
2444
2445 const auto rect = Rect(0, 0, 1, 1);
2446 const renderengine::DisplaySettings display{
2447 .physicalDisplay = rect,
2448 .clip = rect,
2449 };
2450
2451 const renderengine::LayerSettings redLayer{
2452 .geometry.boundaries = rect.toFloatRect(),
2453 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
2454 .alpha = 1.0f,
2455 };
2456
2457 // The next layer will overwrite redLayer with a GraphicBuffer that is green
2458 // applied with a translucent alpha.
Alec Mouria90a5702021-04-16 16:36:21 +00002459 const auto buf = allocateSourceBuffer(1, 1);
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002460 {
2461 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00002462 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2463 reinterpret_cast<void**>(&pixels));
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002464 pixels[0] = 0;
2465 pixels[1] = 255;
2466 pixels[2] = 0;
2467 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00002468 buf->getBuffer()->unlock();
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002469 }
2470
2471 const renderengine::LayerSettings greenLayer{
2472 .geometry.boundaries = rect.toFloatRect(),
2473 .source =
2474 renderengine::PixelSource{
2475 .buffer =
2476 renderengine::Buffer{
2477 .buffer = buf,
2478 .usePremultipliedAlpha = true,
2479 },
2480 },
2481 .alpha = 0.5f,
2482 .disableBlending = true,
2483 };
2484
Sally Qi59a9f502021-10-12 18:53:23 +00002485 std::vector<renderengine::LayerSettings> layers{redLayer, greenLayer};
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002486 invokeDraw(display, layers);
2487 expectBufferColor(rect, 0, 128, 0, 128);
2488}
2489
Tianhao Yao67dd7122022-02-22 17:48:33 +00002490TEST_P(RenderEngineTest, testBorder) {
2491 if (GetParam()->type() != renderengine::RenderEngine::RenderEngineType::SKIA_GL) {
2492 GTEST_SKIP();
2493 }
2494
2495 if (!GetParam()->useColorManagement()) {
2496 GTEST_SKIP();
2497 }
2498
2499 initializeRenderEngine();
2500
2501 const ui::Dataspace dataspace = ui::Dataspace::V0_SRGB;
2502
2503 const auto displayRect = Rect(1080, 2280);
2504 renderengine::DisplaySettings display{
2505 .physicalDisplay = displayRect,
2506 .clip = displayRect,
2507 .outputDataspace = dataspace,
2508 };
2509 display.borderInfoList.clear();
2510 renderengine::BorderRenderInfo info;
2511 info.combinedRegion = Region(Rect(99, 99, 199, 199));
Tianhao Yao10cea3c2022-03-30 01:37:22 +00002512 info.width = 20.0f;
2513 info.color = half4{1.0f, 128.0f / 255.0f, 0.0f, 1.0f};
Tianhao Yao67dd7122022-02-22 17:48:33 +00002514 display.borderInfoList.emplace_back(info);
2515
2516 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2517 const renderengine::LayerSettings greenLayer{
2518 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2519 .source =
2520 renderengine::PixelSource{
2521 .buffer =
2522 renderengine::Buffer{
2523 .buffer = greenBuffer,
2524 .usePremultipliedAlpha = true,
2525 },
2526 },
2527 .alpha = 1.0f,
2528 .sourceDataspace = dataspace,
2529 .whitePointNits = 200.f,
2530 };
2531
2532 std::vector<renderengine::LayerSettings> layers;
2533 layers.emplace_back(greenLayer);
2534 invokeDraw(display, layers);
2535
2536 expectBufferColor(Rect(99, 99, 101, 101), 255, 128, 0, 255, 1);
2537}
2538
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002539TEST_P(RenderEngineTest, testDimming) {
2540 if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) {
Alec Mouri85065692022-03-18 00:58:26 +00002541 GTEST_SKIP();
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002542 }
Alec Mouri85065692022-03-18 00:58:26 +00002543
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002544 initializeRenderEngine();
2545
Alec Mouri85065692022-03-18 00:58:26 +00002546 const ui::Dataspace dataspace = ui::Dataspace::V0_SRGB_LINEAR;
2547
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002548 const auto displayRect = Rect(3, 1);
2549 const renderengine::DisplaySettings display{
2550 .physicalDisplay = displayRect,
2551 .clip = displayRect,
Alec Mouri85065692022-03-18 00:58:26 +00002552 .outputDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002553 .targetLuminanceNits = 1000.f,
2554 };
2555
2556 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2557 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2558 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2559
2560 const renderengine::LayerSettings greenLayer{
2561 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2562 .source =
2563 renderengine::PixelSource{
2564 .buffer =
2565 renderengine::Buffer{
2566 .buffer = greenBuffer,
2567 .usePremultipliedAlpha = true,
2568 },
2569 },
2570 .alpha = 1.0f,
Alec Mouri85065692022-03-18 00:58:26 +00002571 .sourceDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002572 .whitePointNits = 200.f,
2573 };
2574
2575 const renderengine::LayerSettings blueLayer{
2576 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2577 .source =
2578 renderengine::PixelSource{
2579 .buffer =
2580 renderengine::Buffer{
2581 .buffer = blueBuffer,
2582 .usePremultipliedAlpha = true,
2583 },
2584 },
2585 .alpha = 1.0f,
Alec Mouri85065692022-03-18 00:58:26 +00002586 .sourceDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002587 .whitePointNits = 1000.f / 51.f,
2588 };
2589
2590 const renderengine::LayerSettings redLayer{
2591 .geometry.boundaries = FloatRect(2.f, 0.f, 3.f, 1.f),
2592 .source =
2593 renderengine::PixelSource{
2594 .buffer =
2595 renderengine::Buffer{
2596 .buffer = redBuffer,
2597 .usePremultipliedAlpha = true,
2598 },
2599 },
2600 .alpha = 1.0f,
Alec Mouri85065692022-03-18 00:58:26 +00002601 .sourceDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002602 // When the white point is not set for a layer, just ignore it and treat it as the same
2603 // as the max layer
2604 .whitePointNits = -1.f,
2605 };
2606
2607 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer, redLayer};
2608 invokeDraw(display, layers);
2609
2610 expectBufferColor(Rect(1, 1), 0, 51, 0, 255, 1);
2611 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 5, 255, 1);
2612 expectBufferColor(Rect(2, 0, 3, 1), 51, 0, 0, 255, 1);
2613}
2614
Alec Mouri85065692022-03-18 00:58:26 +00002615TEST_P(RenderEngineTest, testDimming_inGammaSpace) {
2616 if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) {
2617 GTEST_SKIP();
2618 }
2619 initializeRenderEngine();
2620
2621 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2622 ui::Dataspace::TRANSFER_GAMMA2_2 |
2623 ui::Dataspace::RANGE_FULL);
2624
2625 const auto displayRect = Rect(3, 1);
2626 const renderengine::DisplaySettings display{
2627 .physicalDisplay = displayRect,
2628 .clip = displayRect,
2629 .outputDataspace = dataspace,
2630 .targetLuminanceNits = 1000.f,
2631 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2632 };
2633
2634 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2635 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2636 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2637
2638 const renderengine::LayerSettings greenLayer{
2639 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2640 .source =
2641 renderengine::PixelSource{
2642 .buffer =
2643 renderengine::Buffer{
2644 .buffer = greenBuffer,
2645 .usePremultipliedAlpha = true,
2646 },
2647 },
2648 .alpha = 1.0f,
2649 .sourceDataspace = dataspace,
2650 .whitePointNits = 200.f,
2651 };
2652
2653 const renderengine::LayerSettings blueLayer{
2654 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2655 .source =
2656 renderengine::PixelSource{
2657 .buffer =
2658 renderengine::Buffer{
2659 .buffer = blueBuffer,
2660 .usePremultipliedAlpha = true,
2661 },
2662 },
2663 .alpha = 1.0f,
2664 .sourceDataspace = dataspace,
2665 .whitePointNits = 1000.f / 51.f,
2666 };
2667
2668 const renderengine::LayerSettings redLayer{
2669 .geometry.boundaries = FloatRect(2.f, 0.f, 3.f, 1.f),
2670 .source =
2671 renderengine::PixelSource{
2672 .buffer =
2673 renderengine::Buffer{
2674 .buffer = redBuffer,
2675 .usePremultipliedAlpha = true,
2676 },
2677 },
2678 .alpha = 1.0f,
2679 .sourceDataspace = dataspace,
2680 // When the white point is not set for a layer, just ignore it and treat it as the same
2681 // as the max layer
2682 .whitePointNits = -1.f,
2683 };
2684
2685 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer, redLayer};
2686 invokeDraw(display, layers);
2687
2688 expectBufferColor(Rect(1, 1), 0, 122, 0, 255, 1);
2689 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 42, 255, 1);
2690 expectBufferColor(Rect(2, 0, 3, 1), 122, 0, 0, 255, 1);
2691}
2692
Alec Mouri9bcd1d12022-04-21 22:16:56 +00002693TEST_P(RenderEngineTest, testDimming_inGammaSpace_withDisplayColorTransform) {
2694 if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) {
2695 GTEST_SKIP();
2696 }
2697 initializeRenderEngine();
2698
2699 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2700 ui::Dataspace::TRANSFER_GAMMA2_2 |
2701 ui::Dataspace::RANGE_FULL);
2702
2703 const auto displayRect = Rect(3, 1);
2704 const renderengine::DisplaySettings display{
2705 .physicalDisplay = displayRect,
2706 .clip = displayRect,
2707 .outputDataspace = dataspace,
2708 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
2709 .targetLuminanceNits = 1000.f,
2710 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2711 };
2712
2713 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2714 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2715 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2716
2717 const renderengine::LayerSettings greenLayer{
2718 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2719 .source =
2720 renderengine::PixelSource{
2721 .buffer =
2722 renderengine::Buffer{
2723 .buffer = greenBuffer,
2724 .usePremultipliedAlpha = true,
2725 },
2726 },
2727 .alpha = 1.0f,
2728 .sourceDataspace = dataspace,
2729 .whitePointNits = 200.f,
2730 };
2731
2732 const renderengine::LayerSettings redLayer{
2733 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2734 .source =
2735 renderengine::PixelSource{
2736 .buffer =
2737 renderengine::Buffer{
2738 .buffer = redBuffer,
2739 .usePremultipliedAlpha = true,
2740 },
2741 },
2742 .alpha = 1.0f,
2743 .sourceDataspace = dataspace,
2744 // When the white point is not set for a layer, just ignore it and treat it as the same
2745 // as the max layer
2746 .whitePointNits = -1.f,
2747 };
2748
2749 std::vector<renderengine::LayerSettings> layers{greenLayer, redLayer};
2750 invokeDraw(display, layers);
2751
2752 expectBufferColor(Rect(1, 1), 0, 0, 0, 255, 1);
2753 expectBufferColor(Rect(1, 0, 2, 1), 0, 122, 0, 255, 1);
2754}
2755
2756TEST_P(RenderEngineTest, testDimming_inGammaSpace_withDisplayColorTransform_deviceHandles) {
2757 if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) {
2758 GTEST_SKIP();
2759 }
2760 initializeRenderEngine();
2761
2762 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2763 ui::Dataspace::TRANSFER_GAMMA2_2 |
2764 ui::Dataspace::RANGE_FULL);
2765
2766 const auto displayRect = Rect(3, 1);
2767 const renderengine::DisplaySettings display{
2768 .physicalDisplay = displayRect,
2769 .clip = displayRect,
2770 .outputDataspace = dataspace,
2771 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
2772 .deviceHandlesColorTransform = true,
2773 .targetLuminanceNits = 1000.f,
2774 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2775 };
2776
2777 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2778 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2779 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2780
2781 const renderengine::LayerSettings greenLayer{
2782 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2783 .source =
2784 renderengine::PixelSource{
2785 .buffer =
2786 renderengine::Buffer{
2787 .buffer = greenBuffer,
2788 .usePremultipliedAlpha = true,
2789 },
2790 },
2791 .alpha = 1.0f,
2792 .sourceDataspace = dataspace,
2793 .whitePointNits = 200.f,
2794 };
2795
2796 const renderengine::LayerSettings redLayer{
2797 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2798 .source =
2799 renderengine::PixelSource{
2800 .buffer =
2801 renderengine::Buffer{
2802 .buffer = redBuffer,
2803 .usePremultipliedAlpha = true,
2804 },
2805 },
2806 .alpha = 1.0f,
2807 .sourceDataspace = dataspace,
2808 // When the white point is not set for a layer, just ignore it and treat it as the same
2809 // as the max layer
2810 .whitePointNits = -1.f,
2811 };
2812
2813 std::vector<renderengine::LayerSettings> layers{greenLayer, redLayer};
2814 invokeDraw(display, layers);
2815
2816 expectBufferColor(Rect(1, 1), 0, 122, 0, 255, 1);
2817 expectBufferColor(Rect(1, 0, 2, 1), 122, 0, 0, 255, 1);
2818}
2819
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002820TEST_P(RenderEngineTest, testDimming_withoutTargetLuminance) {
2821 initializeRenderEngine();
2822 if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) {
2823 return;
2824 }
2825
2826 const auto displayRect = Rect(2, 1);
2827 const renderengine::DisplaySettings display{
2828 .physicalDisplay = displayRect,
2829 .clip = displayRect,
2830 .outputDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2831 .targetLuminanceNits = -1.f,
2832 };
2833
2834 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2835 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2836
2837 const renderengine::LayerSettings greenLayer{
2838 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2839 .source =
2840 renderengine::PixelSource{
2841 .buffer =
2842 renderengine::Buffer{
2843 .buffer = greenBuffer,
2844 .usePremultipliedAlpha = true,
2845 },
2846 },
2847 .alpha = 1.0f,
2848 .sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2849 .whitePointNits = 200.f,
2850 };
2851
2852 const renderengine::LayerSettings blueLayer{
2853 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2854 .source =
2855 renderengine::PixelSource{
2856 .buffer =
2857 renderengine::Buffer{
2858 .buffer = blueBuffer,
2859 .usePremultipliedAlpha = true,
2860 },
2861 },
2862 .alpha = 1.0f,
2863 .sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2864 .whitePointNits = 1000.f,
2865 };
2866
2867 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer};
2868 invokeDraw(display, layers);
2869
2870 expectBufferColor(Rect(1, 1), 0, 51, 0, 255, 1);
2871 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 255, 255);
2872}
2873
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002874TEST_P(RenderEngineTest, test_isOpaque) {
2875 initializeRenderEngine();
2876
2877 const auto rect = Rect(0, 0, 1, 1);
2878 const renderengine::DisplaySettings display{
2879 .physicalDisplay = rect,
2880 .clip = rect,
2881 .outputDataspace = ui::Dataspace::DISPLAY_P3,
2882 };
2883
2884 // Create an unpremul buffer that is green with no alpha. Using isOpaque
2885 // should make the green show.
2886 const auto buf = allocateSourceBuffer(1, 1);
2887 {
2888 uint8_t* pixels;
2889 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2890 reinterpret_cast<void**>(&pixels));
2891 pixels[0] = 0;
2892 pixels[1] = 255;
2893 pixels[2] = 0;
2894 pixels[3] = 0;
2895 buf->getBuffer()->unlock();
2896 }
2897
2898 const renderengine::LayerSettings greenLayer{
2899 .geometry.boundaries = rect.toFloatRect(),
2900 .source =
2901 renderengine::PixelSource{
2902 .buffer =
2903 renderengine::Buffer{
2904 .buffer = buf,
2905 // Although the pixels are not
2906 // premultiplied in practice, this
2907 // matches the input we see.
2908 .usePremultipliedAlpha = true,
2909 .isOpaque = true,
2910 },
2911 },
2912 .alpha = 1.0f,
2913 };
2914
Sally Qi59a9f502021-10-12 18:53:23 +00002915 std::vector<renderengine::LayerSettings> layers{greenLayer};
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002916 invokeDraw(display, layers);
2917
2918 if (GetParam()->useColorManagement()) {
2919 expectBufferColor(rect, 117, 251, 76, 255);
2920 } else {
2921 expectBufferColor(rect, 0, 255, 0, 255);
2922 }
2923}
Alec Mouri4049b532021-10-15 20:59:33 -07002924
Alec Mouri4049b532021-10-15 20:59:33 -07002925TEST_P(RenderEngineTest, test_tonemapPQMatches) {
2926 if (!GetParam()->useColorManagement()) {
Alec Mouri5a493722022-01-26 16:43:02 -08002927 GTEST_SKIP();
Alec Mouri4049b532021-10-15 20:59:33 -07002928 }
2929
2930 if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) {
Alec Mouri5a493722022-01-26 16:43:02 -08002931 GTEST_SKIP();
Alec Mouri4049b532021-10-15 20:59:33 -07002932 }
2933
2934 initializeRenderEngine();
2935
Alec Mouri5a493722022-01-26 16:43:02 -08002936 tonemap(
2937 static_cast<ui::Dataspace>(HAL_DATASPACE_STANDARD_BT2020 |
2938 HAL_DATASPACE_TRANSFER_ST2084 | HAL_DATASPACE_RANGE_FULL),
2939 [](vec3 color) { return EOTF_PQ(color); },
2940 [](vec3 color, float) {
2941 static constexpr float kMaxPQLuminance = 10000.f;
2942 return color * kMaxPQLuminance;
2943 });
2944}
Alec Mouri4049b532021-10-15 20:59:33 -07002945
Alec Mouri5a493722022-01-26 16:43:02 -08002946TEST_P(RenderEngineTest, test_tonemapHLGMatches) {
2947 if (!GetParam()->useColorManagement()) {
2948 GTEST_SKIP();
Alec Mouri4049b532021-10-15 20:59:33 -07002949 }
2950
Alec Mouri5a493722022-01-26 16:43:02 -08002951 if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) {
2952 GTEST_SKIP();
2953 }
Alec Mouri4049b532021-10-15 20:59:33 -07002954
Alec Mouri5a493722022-01-26 16:43:02 -08002955 initializeRenderEngine();
Alec Mouri4049b532021-10-15 20:59:33 -07002956
Alec Mouri5a493722022-01-26 16:43:02 -08002957 tonemap(
2958 static_cast<ui::Dataspace>(HAL_DATASPACE_STANDARD_BT2020 | HAL_DATASPACE_TRANSFER_HLG |
2959 HAL_DATASPACE_RANGE_FULL),
2960 [](vec3 color) { return EOTF_HLG(color); },
2961 [](vec3 color, float currentLuminaceNits) {
2962 static constexpr float kMaxHLGLuminance = 1000.f;
Alec Mouri7a577452022-03-04 23:41:38 +00002963 return color * kMaxHLGLuminance;
Alec Mouri5a493722022-01-26 16:43:02 -08002964 });
Alec Mouri4049b532021-10-15 20:59:33 -07002965}
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -05002966
2967TEST_P(RenderEngineTest, r8_behaves_as_mask) {
2968 if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) {
2969 return;
2970 }
2971
2972 initializeRenderEngine();
2973
2974 const auto r8Buffer = allocateR8Buffer(2, 1);
2975 if (!r8Buffer) {
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05002976 GTEST_SKIP() << "Test is only necessary on devices that support r8";
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -05002977 return;
2978 }
2979 {
2980 uint8_t* pixels;
2981 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2982 reinterpret_cast<void**>(&pixels));
2983 // This will be drawn on top of a green buffer. We'll verify that 255
2984 // results in keeping the original green and 0 results in black.
2985 pixels[0] = 0;
2986 pixels[1] = 255;
2987 r8Buffer->getBuffer()->unlock();
2988 }
2989
2990 const auto rect = Rect(0, 0, 2, 1);
2991 const renderengine::DisplaySettings display{
2992 .physicalDisplay = rect,
2993 .clip = rect,
2994 .outputDataspace = ui::Dataspace::SRGB,
2995 };
2996
2997 const auto greenBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(0, 255, 0, 255));
2998 const renderengine::LayerSettings greenLayer{
2999 .geometry.boundaries = rect.toFloatRect(),
3000 .source =
3001 renderengine::PixelSource{
3002 .buffer =
3003 renderengine::Buffer{
3004 .buffer = greenBuffer,
3005 },
3006 },
3007 .alpha = 1.0f,
3008 };
3009 const renderengine::LayerSettings r8Layer{
3010 .geometry.boundaries = rect.toFloatRect(),
3011 .source =
3012 renderengine::PixelSource{
3013 .buffer =
3014 renderengine::Buffer{
3015 .buffer = r8Buffer,
3016 },
3017 },
3018 .alpha = 1.0f,
3019 };
3020
3021 std::vector<renderengine::LayerSettings> layers{greenLayer, r8Layer};
3022 invokeDraw(display, layers);
3023
3024 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 255);
3025 expectBufferColor(Rect(1, 0, 2, 1), 0, 255, 0, 255);
3026}
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003027
3028TEST_P(RenderEngineTest, r8_respects_color_transform) {
3029 if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) {
3030 return;
3031 }
3032
3033 initializeRenderEngine();
3034
3035 const auto r8Buffer = allocateR8Buffer(2, 1);
3036 if (!r8Buffer) {
3037 GTEST_SKIP() << "Test is only necessary on devices that support r8";
3038 return;
3039 }
3040 {
3041 uint8_t* pixels;
3042 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
3043 reinterpret_cast<void**>(&pixels));
3044 pixels[0] = 0;
3045 pixels[1] = 255;
3046 r8Buffer->getBuffer()->unlock();
3047 }
3048
3049 const auto rect = Rect(0, 0, 2, 1);
3050 const renderengine::DisplaySettings display{
3051 .physicalDisplay = rect,
3052 .clip = rect,
3053 .outputDataspace = ui::Dataspace::SRGB,
3054 // Verify that the R8 layer respects the color transform when
3055 // deviceHandlesColorTransform is false. This transform converts
3056 // pure red to pure green. That will occur when the R8 buffer is
3057 // 255. When the R8 buffer is 0, it will still change to black, as
3058 // with r8_behaves_as_mask.
Alec Mouri9bcd1d12022-04-21 22:16:56 +00003059 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003060 .deviceHandlesColorTransform = false,
3061 };
3062
3063 const auto redBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(255, 0, 0, 255));
3064 const renderengine::LayerSettings redLayer{
3065 .geometry.boundaries = rect.toFloatRect(),
3066 .source =
3067 renderengine::PixelSource{
3068 .buffer =
3069 renderengine::Buffer{
3070 .buffer = redBuffer,
3071 },
3072 },
3073 .alpha = 1.0f,
3074 };
3075 const renderengine::LayerSettings r8Layer{
3076 .geometry.boundaries = rect.toFloatRect(),
3077 .source =
3078 renderengine::PixelSource{
3079 .buffer =
3080 renderengine::Buffer{
3081 .buffer = r8Buffer,
3082 },
3083 },
3084 .alpha = 1.0f,
3085 };
3086
3087 std::vector<renderengine::LayerSettings> layers{redLayer, r8Layer};
3088 invokeDraw(display, layers);
3089
3090 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 255);
3091 expectBufferColor(Rect(1, 0, 2, 1), 0, 255, 0, 255);
3092}
3093
3094TEST_P(RenderEngineTest, r8_respects_color_transform_when_device_handles) {
3095 if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) {
3096 return;
3097 }
3098
3099 initializeRenderEngine();
3100
3101 const auto r8Buffer = allocateR8Buffer(2, 1);
3102 if (!r8Buffer) {
3103 GTEST_SKIP() << "Test is only necessary on devices that support r8";
3104 return;
3105 }
3106 {
3107 uint8_t* pixels;
3108 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
3109 reinterpret_cast<void**>(&pixels));
3110 pixels[0] = 0;
3111 pixels[1] = 255;
3112 r8Buffer->getBuffer()->unlock();
3113 }
3114
3115 const auto rect = Rect(0, 0, 2, 1);
3116 const renderengine::DisplaySettings display{
3117 .physicalDisplay = rect,
3118 .clip = rect,
3119 .outputDataspace = ui::Dataspace::SRGB,
3120 // If deviceHandlesColorTransform is true, pixels where the A8
3121 // buffer is opaque are unaffected. If the colorTransform is
3122 // invertible, pixels where the A8 buffer are transparent have the
3123 // inverse applied to them so that the DPU will convert them back to
3124 // black. Test with an arbitrary, invertible matrix.
3125 .colorTransform = mat4(1, 0, 0, 2,
3126 3, 1, 2, 5,
3127 0, 5, 3, 0,
3128 0, 1, 0, 2),
3129 .deviceHandlesColorTransform = true,
3130 };
3131
3132 const auto redBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(255, 0, 0, 255));
3133 const renderengine::LayerSettings redLayer{
3134 .geometry.boundaries = rect.toFloatRect(),
3135 .source =
3136 renderengine::PixelSource{
3137 .buffer =
3138 renderengine::Buffer{
3139 .buffer = redBuffer,
3140 },
3141 },
3142 .alpha = 1.0f,
3143 };
3144 const renderengine::LayerSettings r8Layer{
3145 .geometry.boundaries = rect.toFloatRect(),
3146 .source =
3147 renderengine::PixelSource{
3148 .buffer =
3149 renderengine::Buffer{
3150 .buffer = r8Buffer,
3151 },
3152 },
3153 .alpha = 1.0f,
3154 };
3155
3156 std::vector<renderengine::LayerSettings> layers{redLayer, r8Layer};
3157 invokeDraw(display, layers);
3158
3159 expectBufferColor(Rect(1, 0, 2, 1), 255, 0, 0, 255); // Still red.
3160 expectBufferColor(Rect(0, 0, 1, 1), 0, 70, 0, 255);
3161}
Leon Scroggins III45be9182022-04-27 10:37:11 -04003162
3163TEST_P(RenderEngineTest, primeShaderCache) {
3164 if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) {
3165 GTEST_SKIP();
3166 }
3167
3168 initializeRenderEngine();
3169
3170 auto fut = mRE->primeCache();
3171 if (fut.valid()) {
3172 fut.wait();
3173 }
3174
3175 const int minimumExpectedShadersCompiled = GetParam()->useColorManagement() ? 60 : 30;
3176 ASSERT_GT(static_cast<skia::SkiaGLRenderEngine*>(mRE.get())->reportShadersCompiled(),
3177 minimumExpectedShadersCompiled);
3178}
Derek Sollenbergerd3f60652021-06-11 15:34:36 -04003179} // namespace renderengine
Alec Mouri6e57f682018-09-29 20:45:08 -07003180} // namespace android
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08003181
3182// TODO(b/129481165): remove the #pragma below and fix conversion issues
Marin Shalamanovbed7fd32020-12-21 20:02:20 +01003183#pragma clang diagnostic pop // ignored "-Wconversion -Wextra"