blob: d23063c84d79036dc7c6f97693147f9fc92dcc81 [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::
Ady Abrahamd11bade2022-08-01 16:18:03 -0700235 ExternalTexture>(sp<GraphicBuffer>::
236 make(DEFAULT_DISPLAY_WIDTH, 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"),
Alec Mouria90a5702021-04-16 16:36:21 +0000243 *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::
Ady Abrahamd11bade2022-08-01 16:18:03 -0700254 ExternalTexture>(sp<GraphicBuffer>::
255 make(width, height, 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"),
Alec Mouria90a5702021-04-16 16:36:21 +0000260 *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) {
Ady Abrahamd11bade2022-08-01 16:18:03 -0700288 const auto kUsageFlags =
289 static_cast<uint64_t>(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
290 GRALLOC_USAGE_HW_TEXTURE);
291 auto buffer =
292 sp<GraphicBuffer>::make(static_cast<uint32_t>(width), static_cast<uint32_t>(height),
293 android::PIXEL_FORMAT_R_8, 1u, kUsageFlags, "r8");
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -0500294 if (buffer->initCheck() != 0) {
295 // Devices are not required to support R8.
296 return nullptr;
297 }
298 return std::make_shared<
299 renderengine::impl::ExternalTexture>(std::move(buffer), *mRE,
300 renderengine::impl::ExternalTexture::Usage::
301 READABLE);
302 }
303
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800304 RenderEngineTest() {
305 const ::testing::TestInfo* const test_info =
306 ::testing::UnitTest::GetInstance()->current_test_info();
307 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800308 }
Alec Mouri1089aed2018-10-25 21:33:57 -0700309
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800310 ~RenderEngineTest() {
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800311 if (WRITE_BUFFER_TO_FILE_ON_FAILURE && ::testing::Test::HasFailure()) {
312 writeBufferToFile("/data/texture_out_");
313 }
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800314 for (uint32_t texName : mTexNames) {
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800315 mRE->deleteTextures(1, &texName);
Alec Mouric0aae732021-01-12 13:32:18 -0800316 if (mGLESRE != nullptr) {
317 EXPECT_FALSE(mGLESRE->isTextureNameKnownForTesting(texName));
318 }
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800319 }
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800320 const ::testing::TestInfo* const test_info =
321 ::testing::UnitTest::GetInstance()->current_test_info();
322 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800323 }
324
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800325 void writeBufferToFile(const char* basename) {
326 std::string filename(basename);
327 filename.append(::testing::UnitTest::GetInstance()->current_test_info()->name());
328 filename.append(".ppm");
329 std::ofstream file(filename.c_str(), std::ios::binary);
330 if (!file.is_open()) {
331 ALOGE("Unable to open file: %s", filename.c_str());
332 ALOGE("You may need to do: \"adb shell setenforce 0\" to enable "
333 "surfaceflinger to write debug images");
334 return;
335 }
336
Alec Mouri1089aed2018-10-25 21:33:57 -0700337 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +0000338 mBuffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
339 reinterpret_cast<void**>(&pixels));
Alec Mouri1089aed2018-10-25 21:33:57 -0700340
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800341 file << "P6\n";
Alec Mouria90a5702021-04-16 16:36:21 +0000342 file << mBuffer->getBuffer()->getWidth() << "\n";
343 file << mBuffer->getBuffer()->getHeight() << "\n";
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800344 file << 255 << "\n";
345
Alec Mouria90a5702021-04-16 16:36:21 +0000346 std::vector<uint8_t> outBuffer(mBuffer->getBuffer()->getWidth() *
347 mBuffer->getBuffer()->getHeight() * 3);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800348 auto outPtr = reinterpret_cast<uint8_t*>(outBuffer.data());
349
Alec Mouria90a5702021-04-16 16:36:21 +0000350 for (int32_t j = 0; j < mBuffer->getBuffer()->getHeight(); j++) {
351 const uint8_t* src = pixels + (mBuffer->getBuffer()->getStride() * j) * 4;
352 for (int32_t i = 0; i < mBuffer->getBuffer()->getWidth(); i++) {
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800353 // Only copy R, G and B components
354 outPtr[0] = src[0];
355 outPtr[1] = src[1];
356 outPtr[2] = src[2];
357 outPtr += 3;
358
359 src += 4;
360 }
361 }
362 file.write(reinterpret_cast<char*>(outBuffer.data()), outBuffer.size());
Alec Mouria90a5702021-04-16 16:36:21 +0000363 mBuffer->getBuffer()->unlock();
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800364 }
365
366 void expectBufferColor(const Region& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
367 size_t c;
368 Rect const* rect = region.getArray(&c);
369 for (size_t i = 0; i < c; i++, rect++) {
370 expectBufferColor(*rect, r, g, b, a);
371 }
372 }
373
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -0400374 void expectBufferColor(const Point& point, uint8_t r, uint8_t g, uint8_t b, uint8_t a,
375 uint8_t tolerance = 0) {
376 expectBufferColor(Rect(point.x, point.y, point.x + 1, point.y + 1), r, g, b, a, tolerance);
377 }
378
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800379 void expectBufferColor(const Rect& rect, uint8_t r, uint8_t g, uint8_t b, uint8_t a,
380 uint8_t tolerance = 0) {
Alec Mouri4049b532021-10-15 20:59:33 -0700381 auto generator = [=](Point) { return ubyte4(r, g, b, a); };
382 expectBufferColor(rect, generator, tolerance);
383 }
384
385 using ColorGenerator = std::function<ubyte4(Point location)>;
386
387 void expectBufferColor(const Rect& rect, ColorGenerator generator, uint8_t tolerance = 0) {
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800388 auto colorCompare = [tolerance](const uint8_t* colorA, const uint8_t* colorB) {
389 auto colorBitCompare = [tolerance](uint8_t a, uint8_t b) {
390 uint8_t tmp = a >= b ? a - b : b - a;
391 return tmp <= tolerance;
392 };
393 return std::equal(colorA, colorA + 4, colorB, colorBitCompare);
Alec Mouri1089aed2018-10-25 21:33:57 -0700394 };
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800395
Alec Mouri4049b532021-10-15 20:59:33 -0700396 expectBufferColor(rect, generator, colorCompare);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800397 }
398
Alec Mouri4049b532021-10-15 20:59:33 -0700399 void expectBufferColor(const Rect& region, ColorGenerator generator,
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800400 std::function<bool(const uint8_t* a, const uint8_t* b)> colorCompare) {
401 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +0000402 mBuffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
403 reinterpret_cast<void**>(&pixels));
Alec Mouri1089aed2018-10-25 21:33:57 -0700404 int32_t maxFails = 10;
405 int32_t fails = 0;
406 for (int32_t j = 0; j < region.getHeight(); j++) {
Alec Mouria90a5702021-04-16 16:36:21 +0000407 const uint8_t* src = pixels +
408 (mBuffer->getBuffer()->getStride() * (region.top + j) + region.left) * 4;
Alec Mouri1089aed2018-10-25 21:33:57 -0700409 for (int32_t i = 0; i < region.getWidth(); i++) {
Alec Mouri4049b532021-10-15 20:59:33 -0700410 const auto location = Point(region.left + i, region.top + j);
411 const ubyte4 colors = generator(location);
412 const uint8_t expected[4] = {colors.r, colors.g, colors.b, colors.a};
413 bool colorMatches = colorCompare(src, expected);
414 EXPECT_TRUE(colorMatches)
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -0400415 << GetParam()->name().c_str() << ": "
Alec Mouri4049b532021-10-15 20:59:33 -0700416 << "pixel @ (" << location.x << ", " << location.y << "): "
417 << "expected (" << static_cast<uint32_t>(colors.r) << ", "
418 << static_cast<uint32_t>(colors.g) << ", "
419 << static_cast<uint32_t>(colors.b) << ", "
420 << static_cast<uint32_t>(colors.a) << "), "
Alec Mouri1089aed2018-10-25 21:33:57 -0700421 << "got (" << static_cast<uint32_t>(src[0]) << ", "
422 << static_cast<uint32_t>(src[1]) << ", " << static_cast<uint32_t>(src[2])
423 << ", " << static_cast<uint32_t>(src[3]) << ")";
424 src += 4;
Alec Mouri4049b532021-10-15 20:59:33 -0700425 if (!colorMatches && ++fails >= maxFails) {
Alec Mouri1089aed2018-10-25 21:33:57 -0700426 break;
427 }
428 }
429 if (fails >= maxFails) {
430 break;
431 }
432 }
Alec Mouria90a5702021-04-16 16:36:21 +0000433 mBuffer->getBuffer()->unlock();
Alec Mouri1089aed2018-10-25 21:33:57 -0700434 }
435
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800436 void expectAlpha(const Rect& rect, uint8_t a) {
Alec Mouri4049b532021-10-15 20:59:33 -0700437 auto generator = [=](Point) { return ubyte4(0, 0, 0, a); };
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800438 auto colorCompare = [](const uint8_t* colorA, const uint8_t* colorB) {
439 return colorA[3] == colorB[3];
440 };
Alec Mouri4049b532021-10-15 20:59:33 -0700441 expectBufferColor(rect, generator, colorCompare);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800442 }
443
444 void expectShadowColor(const renderengine::LayerSettings& castingLayer,
445 const renderengine::ShadowSettings& shadow, const ubyte4& casterColor,
446 const ubyte4& backgroundColor) {
447 const Rect casterRect(castingLayer.geometry.boundaries);
448 Region casterRegion = Region(casterRect);
Vishnu Nair50c0afe2022-07-11 15:04:07 -0700449 const float casterCornerRadius = (castingLayer.geometry.roundedCornersRadius.x +
450 castingLayer.geometry.roundedCornersRadius.y) /
451 2.0;
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800452 if (casterCornerRadius > 0.0f) {
453 // ignore the corners if a corner radius is set
454 Rect cornerRect(casterCornerRadius, casterCornerRadius);
455 casterRegion.subtractSelf(cornerRect.offsetTo(casterRect.left, casterRect.top));
456 casterRegion.subtractSelf(
457 cornerRect.offsetTo(casterRect.right - casterCornerRadius, casterRect.top));
458 casterRegion.subtractSelf(
459 cornerRect.offsetTo(casterRect.left, casterRect.bottom - casterCornerRadius));
460 casterRegion.subtractSelf(cornerRect.offsetTo(casterRect.right - casterCornerRadius,
461 casterRect.bottom - casterCornerRadius));
462 }
463
464 const float shadowInset = shadow.length * -1.0f;
465 const Rect casterWithShadow =
466 Rect(casterRect).inset(shadowInset, shadowInset, shadowInset, shadowInset);
467 const Region shadowRegion = Region(casterWithShadow).subtractSelf(casterRect);
468 const Region backgroundRegion = Region(fullscreenRect()).subtractSelf(casterWithShadow);
469
470 // verify casting layer
471 expectBufferColor(casterRegion, casterColor.r, casterColor.g, casterColor.b, casterColor.a);
472
473 // verify shadows by testing just the alpha since its difficult to validate the shadow color
474 size_t c;
475 Rect const* r = shadowRegion.getArray(&c);
476 for (size_t i = 0; i < c; i++, r++) {
477 expectAlpha(*r, 255);
478 }
479
480 // verify background
481 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
482 backgroundColor.a);
483 }
484
Alec Mouribd17b3b2020-12-17 11:08:30 -0800485 void expectShadowColorWithoutCaster(const FloatRect& casterBounds,
486 const renderengine::ShadowSettings& shadow,
487 const ubyte4& backgroundColor) {
488 const float shadowInset = shadow.length * -1.0f;
489 const Rect casterRect(casterBounds);
490 const Rect shadowRect =
491 Rect(casterRect).inset(shadowInset, shadowInset, shadowInset, shadowInset);
492
493 const Region backgroundRegion =
494 Region(fullscreenRect()).subtractSelf(casterRect).subtractSelf(shadowRect);
495
496 expectAlpha(shadowRect, 255);
497 // (0, 0, 0) fill on the bounds of the layer should be ignored.
498 expectBufferColor(casterRect, 255, 255, 255, 255, 254);
499
500 // verify background
501 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
502 backgroundColor.a);
503 }
504
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800505 static renderengine::ShadowSettings getShadowSettings(const vec2& casterPos, float shadowLength,
506 bool casterIsTranslucent) {
507 renderengine::ShadowSettings shadow;
508 shadow.ambientColor = {0.0f, 0.0f, 0.0f, 0.039f};
509 shadow.spotColor = {0.0f, 0.0f, 0.0f, 0.19f};
510 shadow.lightPos = vec3(casterPos.x, casterPos.y, 0);
511 shadow.lightRadius = 0.0f;
512 shadow.length = shadowLength;
513 shadow.casterIsTranslucent = casterIsTranslucent;
514 return shadow;
515 }
516
Alec Mouri1089aed2018-10-25 21:33:57 -0700517 static Rect fullscreenRect() { return Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT); }
518
519 static Rect offsetRect() {
520 return Rect(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_WIDTH,
521 DEFAULT_DISPLAY_HEIGHT);
522 }
523
524 static Rect offsetRectAtZero() {
525 return Rect(DEFAULT_DISPLAY_WIDTH - DEFAULT_DISPLAY_OFFSET,
526 DEFAULT_DISPLAY_HEIGHT - DEFAULT_DISPLAY_OFFSET);
527 }
528
Sally Qi59a9f502021-10-12 18:53:23 +0000529 void invokeDraw(const renderengine::DisplaySettings& settings,
530 const std::vector<renderengine::LayerSettings>& layers) {
Sally Qi4cabdd02021-08-05 16:45:57 -0700531 std::future<renderengine::RenderEngineResult> result =
532 mRE->drawLayers(settings, layers, mBuffer, true, base::unique_fd());
Sally Qi59a9f502021-10-12 18:53:23 +0000533
Sally Qi4cabdd02021-08-05 16:45:57 -0700534 ASSERT_TRUE(result.valid());
535 auto [status, fence] = result.get();
Alec Mouri1089aed2018-10-25 21:33:57 -0700536
Derek Sollenbergerec411212021-08-25 10:54:47 -0400537 ASSERT_EQ(NO_ERROR, status);
538 if (fence.ok()) {
539 sync_wait(fence.get(), -1);
Alec Mouri1089aed2018-10-25 21:33:57 -0700540 }
541
Alec Mouric0aae732021-01-12 13:32:18 -0800542 if (layers.size() > 0 && mGLESRE != nullptr) {
Alec Mouria90a5702021-04-16 16:36:21 +0000543 ASSERT_TRUE(mGLESRE->isFramebufferImageCachedForTesting(mBuffer->getBuffer()->getId()));
Alec Mourid43ccab2019-03-13 12:23:45 -0700544 }
Alec Mouri1089aed2018-10-25 21:33:57 -0700545 }
546
Alec Mourid43ccab2019-03-13 12:23:45 -0700547 void drawEmptyLayers() {
Alec Mouri6e57f682018-09-29 20:45:08 -0700548 renderengine::DisplaySettings settings;
Sally Qi59a9f502021-10-12 18:53:23 +0000549 std::vector<renderengine::LayerSettings> layers;
Alec Mouric0aae732021-01-12 13:32:18 -0800550 invokeDraw(settings, layers);
Alec Mouri6e57f682018-09-29 20:45:08 -0700551 }
552
Alec Mouri1089aed2018-10-25 21:33:57 -0700553 template <typename SourceVariant>
554 void fillBuffer(half r, half g, half b, half a);
555
556 template <typename SourceVariant>
557 void fillRedBuffer();
558
559 template <typename SourceVariant>
560 void fillGreenBuffer();
561
562 template <typename SourceVariant>
563 void fillBlueBuffer();
564
565 template <typename SourceVariant>
566 void fillRedTransparentBuffer();
567
568 template <typename SourceVariant>
569 void fillRedOffsetBuffer();
570
571 template <typename SourceVariant>
572 void fillBufferPhysicalOffset();
573
574 template <typename SourceVariant>
Alec Mouri5a6d8572020-03-23 23:56:15 -0700575 void fillBufferCheckers(uint32_t rotation);
Alec Mouri1089aed2018-10-25 21:33:57 -0700576
577 template <typename SourceVariant>
578 void fillBufferCheckersRotate0();
579
580 template <typename SourceVariant>
581 void fillBufferCheckersRotate90();
582
583 template <typename SourceVariant>
584 void fillBufferCheckersRotate180();
585
586 template <typename SourceVariant>
587 void fillBufferCheckersRotate270();
588
589 template <typename SourceVariant>
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800590 void fillBufferWithLayerTransform();
591
592 template <typename SourceVariant>
Alec Mouri1089aed2018-10-25 21:33:57 -0700593 void fillBufferLayerTransform();
594
595 template <typename SourceVariant>
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800596 void fillBufferWithColorTransform();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800597
598 template <typename SourceVariant>
Alec Mouri1089aed2018-10-25 21:33:57 -0700599 void fillBufferColorTransform();
600
Alec Mouri7c94edb2018-12-03 21:23:26 -0800601 template <typename SourceVariant>
Sally Qi2019fd22021-11-22 10:19:04 -0800602 void fillBufferWithColorTransformAndSourceDataspace(const ui::Dataspace sourceDataspace);
603
604 template <typename SourceVariant>
605 void fillBufferColorTransformAndSourceDataspace();
606
607 template <typename SourceVariant>
608 void fillBufferWithColorTransformAndOutputDataspace(const ui::Dataspace outputDataspace);
609
610 template <typename SourceVariant>
611 void fillBufferColorTransformAndOutputDataspace();
612
613 template <typename SourceVariant>
KaiChieh Chuangda2845c2020-12-14 16:49:38 +0800614 void fillBufferWithColorTransformZeroLayerAlpha();
615
616 template <typename SourceVariant>
617 void fillBufferColorTransformZeroLayerAlpha();
618
619 template <typename SourceVariant>
Alec Mouri7c94edb2018-12-03 21:23:26 -0800620 void fillRedBufferWithRoundedCorners();
621
622 template <typename SourceVariant>
623 void fillBufferWithRoundedCorners();
624
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000625 template <typename SourceVariant>
Lucas Dupin19c8f0e2019-11-25 17:55:44 -0800626 void fillBufferAndBlurBackground();
627
628 template <typename SourceVariant>
Alec Mourie8489fd2021-04-29 16:08:56 -0700629 void fillSmallLayerAndBlurBackground();
630
631 template <typename SourceVariant>
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000632 void overlayCorners();
633
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800634 void fillRedBufferTextureTransform();
635
636 void fillBufferTextureTransform();
637
638 void fillRedBufferWithPremultiplyAlpha();
639
640 void fillBufferWithPremultiplyAlpha();
641
642 void fillRedBufferWithoutPremultiplyAlpha();
643
644 void fillBufferWithoutPremultiplyAlpha();
645
Alec Mouriac335532018-11-12 15:01:33 -0800646 void fillGreenColorBufferThenClearRegion();
647
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800648 template <typename SourceVariant>
649 void drawShadow(const renderengine::LayerSettings& castingLayer,
650 const renderengine::ShadowSettings& shadow, const ubyte4& casterColor,
651 const ubyte4& backgroundColor);
652
Alec Mouribd17b3b2020-12-17 11:08:30 -0800653 void drawShadowWithoutCaster(const FloatRect& castingBounds,
654 const renderengine::ShadowSettings& shadow,
655 const ubyte4& backgroundColor);
656
Alec Mouri5a493722022-01-26 16:43:02 -0800657 // Tonemaps grey values from sourceDataspace -> Display P3 and checks that GPU and CPU
658 // implementations are identical Also implicitly checks that the injected tonemap shader
659 // compiles
660 void tonemap(ui::Dataspace sourceDataspace, std::function<vec3(vec3)> eotf,
661 std::function<vec3(vec3, float)> scaleOotf);
662
Alec Mouric0aae732021-01-12 13:32:18 -0800663 void initializeRenderEngine();
664
665 std::unique_ptr<renderengine::RenderEngine> mRE;
Alec Mouria90a5702021-04-16 16:36:21 +0000666 std::shared_ptr<renderengine::ExternalTexture> mBuffer;
Alec Mouric0aae732021-01-12 13:32:18 -0800667 // GLESRenderEngine for testing GLES-specific behavior.
668 // Owened by mRE, but this is downcasted.
669 renderengine::gl::GLESRenderEngine* mGLESRE = nullptr;
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800670
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800671 std::vector<uint32_t> mTexNames;
Alec Mouri6e57f682018-09-29 20:45:08 -0700672};
673
Alec Mouric0aae732021-01-12 13:32:18 -0800674void RenderEngineTest::initializeRenderEngine() {
675 const auto& renderEngineFactory = GetParam();
676 if (renderEngineFactory->type() == renderengine::RenderEngine::RenderEngineType::GLES) {
677 // Only GLESRenderEngine exposes test-only methods. Provide a pointer to the
678 // GLESRenderEngine if we're using it so that we don't need to dynamic_cast
679 // every time.
680 std::unique_ptr<renderengine::gl::GLESRenderEngine> renderEngine =
681 renderEngineFactory->createGLESRenderEngine();
682 mGLESRE = renderEngine.get();
683 mRE = std::move(renderEngine);
684 } else {
685 mRE = renderEngineFactory->createRenderEngine();
686 }
Alec Mouria90a5702021-04-16 16:36:21 +0000687 mBuffer = allocateDefaultBuffer();
Alec Mouric0aae732021-01-12 13:32:18 -0800688}
689
Alec Mouri1089aed2018-10-25 21:33:57 -0700690struct ColorSourceVariant {
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800691 static void fillColor(renderengine::LayerSettings& layer, half r, half g, half b,
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800692 RenderEngineTest* /*fixture*/) {
Alec Mouri1089aed2018-10-25 21:33:57 -0700693 layer.source.solidColor = half3(r, g, b);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800694 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700695 }
696};
697
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800698struct RelaxOpaqueBufferVariant {
699 static void setOpaqueBit(renderengine::LayerSettings& layer) {
700 layer.source.buffer.isOpaque = false;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800701 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800702 }
703
704 static uint8_t getAlphaChannel() { return 255; }
705};
706
707struct ForceOpaqueBufferVariant {
708 static void setOpaqueBit(renderengine::LayerSettings& layer) {
709 layer.source.buffer.isOpaque = true;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800710 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800711 }
712
713 static uint8_t getAlphaChannel() {
714 // The isOpaque bit will override the alpha channel, so this should be
715 // arbitrary.
Alec Mouric0aae732021-01-12 13:32:18 -0800716 return 50;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800717 }
718};
719
720template <typename OpaquenessVariant>
721struct BufferSourceVariant {
722 static void fillColor(renderengine::LayerSettings& layer, half r, half g, half b,
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800723 RenderEngineTest* fixture) {
Alec Mouria90a5702021-04-16 16:36:21 +0000724 const auto buf = fixture->allocateSourceBuffer(1, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800725 uint32_t texName;
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800726 fixture->mRE->genTextures(1, &texName);
727 fixture->mTexNames.push_back(texName);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800728
729 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +0000730 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
731 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800732
Alec Mouria90a5702021-04-16 16:36:21 +0000733 for (int32_t j = 0; j < buf->getBuffer()->getHeight(); j++) {
734 uint8_t* iter = pixels + (buf->getBuffer()->getStride() * j) * 4;
735 for (int32_t i = 0; i < buf->getBuffer()->getWidth(); i++) {
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800736 iter[0] = uint8_t(r * 255);
737 iter[1] = uint8_t(g * 255);
738 iter[2] = uint8_t(b * 255);
739 iter[3] = OpaquenessVariant::getAlphaChannel();
740 iter += 4;
741 }
742 }
743
Alec Mouria90a5702021-04-16 16:36:21 +0000744 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800745
746 layer.source.buffer.buffer = buf;
747 layer.source.buffer.textureName = texName;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800748 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800749 OpaquenessVariant::setOpaqueBit(layer);
750 }
751};
752
Alec Mouri1089aed2018-10-25 21:33:57 -0700753template <typename SourceVariant>
754void RenderEngineTest::fillBuffer(half r, half g, half b, half a) {
755 renderengine::DisplaySettings settings;
756 settings.physicalDisplay = fullscreenRect();
757 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800758 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700759
Sally Qi59a9f502021-10-12 18:53:23 +0000760 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700761
762 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800763 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700764 layer.geometry.boundaries = fullscreenRect().toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800765 SourceVariant::fillColor(layer, r, g, b, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700766 layer.alpha = a;
767
Sally Qi59a9f502021-10-12 18:53:23 +0000768 layers.push_back(layer);
Alec Mouri1089aed2018-10-25 21:33:57 -0700769
Alec Mouric0aae732021-01-12 13:32:18 -0800770 invokeDraw(settings, layers);
Alec Mouri1089aed2018-10-25 21:33:57 -0700771}
772
773template <typename SourceVariant>
774void RenderEngineTest::fillRedBuffer() {
775 fillBuffer<SourceVariant>(1.0f, 0.0f, 0.0f, 1.0f);
776 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
777}
778
779template <typename SourceVariant>
780void RenderEngineTest::fillGreenBuffer() {
781 fillBuffer<SourceVariant>(0.0f, 1.0f, 0.0f, 1.0f);
782 expectBufferColor(fullscreenRect(), 0, 255, 0, 255);
783}
784
785template <typename SourceVariant>
786void RenderEngineTest::fillBlueBuffer() {
787 fillBuffer<SourceVariant>(0.0f, 0.0f, 1.0f, 1.0f);
788 expectBufferColor(fullscreenRect(), 0, 0, 255, 255);
789}
790
791template <typename SourceVariant>
792void RenderEngineTest::fillRedTransparentBuffer() {
793 fillBuffer<SourceVariant>(1.0f, 0.0f, 0.0f, .2f);
794 expectBufferColor(fullscreenRect(), 51, 0, 0, 51);
795}
796
797template <typename SourceVariant>
798void RenderEngineTest::fillRedOffsetBuffer() {
799 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800800 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700801 settings.physicalDisplay = offsetRect();
802 settings.clip = offsetRectAtZero();
803
Sally Qi59a9f502021-10-12 18:53:23 +0000804 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700805
806 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800807 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700808 layer.geometry.boundaries = offsetRectAtZero().toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800809 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700810 layer.alpha = 1.0f;
811
Sally Qi59a9f502021-10-12 18:53:23 +0000812 layers.push_back(layer);
Alec Mouric0aae732021-01-12 13:32:18 -0800813 invokeDraw(settings, layers);
Alec Mouri1089aed2018-10-25 21:33:57 -0700814}
815
816template <typename SourceVariant>
817void RenderEngineTest::fillBufferPhysicalOffset() {
818 fillRedOffsetBuffer<SourceVariant>();
819
820 expectBufferColor(Rect(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_WIDTH,
821 DEFAULT_DISPLAY_HEIGHT),
822 255, 0, 0, 255);
823 Rect offsetRegionLeft(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_HEIGHT);
824 Rect offsetRegionTop(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_OFFSET);
825
826 expectBufferColor(offsetRegionLeft, 0, 0, 0, 0);
827 expectBufferColor(offsetRegionTop, 0, 0, 0, 0);
828}
829
830template <typename SourceVariant>
Alec Mouri5a6d8572020-03-23 23:56:15 -0700831void RenderEngineTest::fillBufferCheckers(uint32_t orientationFlag) {
Alec Mouri1089aed2018-10-25 21:33:57 -0700832 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800833 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700834 settings.physicalDisplay = fullscreenRect();
835 // Here logical space is 2x2
836 settings.clip = Rect(2, 2);
Alec Mouri5a6d8572020-03-23 23:56:15 -0700837 settings.orientation = orientationFlag;
Alec Mouri1089aed2018-10-25 21:33:57 -0700838
Sally Qi59a9f502021-10-12 18:53:23 +0000839 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700840
841 renderengine::LayerSettings layerOne;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800842 layerOne.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700843 Rect rectOne(0, 0, 1, 1);
844 layerOne.geometry.boundaries = rectOne.toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800845 SourceVariant::fillColor(layerOne, 1.0f, 0.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700846 layerOne.alpha = 1.0f;
847
848 renderengine::LayerSettings layerTwo;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800849 layerTwo.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700850 Rect rectTwo(0, 1, 1, 2);
851 layerTwo.geometry.boundaries = rectTwo.toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800852 SourceVariant::fillColor(layerTwo, 0.0f, 1.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700853 layerTwo.alpha = 1.0f;
854
855 renderengine::LayerSettings layerThree;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800856 layerThree.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700857 Rect rectThree(1, 0, 2, 1);
858 layerThree.geometry.boundaries = rectThree.toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800859 SourceVariant::fillColor(layerThree, 0.0f, 0.0f, 1.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700860 layerThree.alpha = 1.0f;
861
Sally Qi59a9f502021-10-12 18:53:23 +0000862 layers.push_back(layerOne);
863 layers.push_back(layerTwo);
864 layers.push_back(layerThree);
Alec Mouri1089aed2018-10-25 21:33:57 -0700865
Alec Mouric0aae732021-01-12 13:32:18 -0800866 invokeDraw(settings, layers);
Alec Mouri1089aed2018-10-25 21:33:57 -0700867}
868
869template <typename SourceVariant>
870void RenderEngineTest::fillBufferCheckersRotate0() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700871 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_0);
Alec Mouri1089aed2018-10-25 21:33:57 -0700872 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0,
873 255);
874 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
875 DEFAULT_DISPLAY_HEIGHT / 2),
876 0, 0, 255, 255);
877 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
878 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
879 0, 0, 0, 0);
880 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
881 DEFAULT_DISPLAY_HEIGHT),
882 0, 255, 0, 255);
883}
884
885template <typename SourceVariant>
886void RenderEngineTest::fillBufferCheckersRotate90() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700887 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_90);
Alec Mouri1089aed2018-10-25 21:33:57 -0700888 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 255, 0,
889 255);
890 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
891 DEFAULT_DISPLAY_HEIGHT / 2),
892 255, 0, 0, 255);
893 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
894 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
895 0, 0, 255, 255);
896 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
897 DEFAULT_DISPLAY_HEIGHT),
898 0, 0, 0, 0);
899}
900
901template <typename SourceVariant>
902void RenderEngineTest::fillBufferCheckersRotate180() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700903 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_180);
Alec Mouri1089aed2018-10-25 21:33:57 -0700904 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 0,
905 0);
906 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
907 DEFAULT_DISPLAY_HEIGHT / 2),
908 0, 255, 0, 255);
909 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
910 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
911 255, 0, 0, 255);
912 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
913 DEFAULT_DISPLAY_HEIGHT),
914 0, 0, 255, 255);
915}
916
917template <typename SourceVariant>
918void RenderEngineTest::fillBufferCheckersRotate270() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700919 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_270);
Alec Mouri1089aed2018-10-25 21:33:57 -0700920 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 255,
921 255);
922 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
923 DEFAULT_DISPLAY_HEIGHT / 2),
924 0, 0, 0, 0);
925 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
926 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
927 0, 255, 0, 255);
928 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
929 DEFAULT_DISPLAY_HEIGHT),
930 255, 0, 0, 255);
931}
932
933template <typename SourceVariant>
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800934void RenderEngineTest::fillBufferWithLayerTransform() {
Alec Mouri1089aed2018-10-25 21:33:57 -0700935 renderengine::DisplaySettings settings;
936 settings.physicalDisplay = fullscreenRect();
937 // Here logical space is 2x2
938 settings.clip = Rect(2, 2);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800939 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700940
Sally Qi59a9f502021-10-12 18:53:23 +0000941 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700942
943 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800944 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700945 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
946 // Translate one pixel diagonally
947 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 -0800948 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700949 layer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
950 layer.alpha = 1.0f;
951
Sally Qi59a9f502021-10-12 18:53:23 +0000952 layers.push_back(layer);
Alec Mouri1089aed2018-10-25 21:33:57 -0700953
Alec Mouric0aae732021-01-12 13:32:18 -0800954 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800955}
Alec Mouri1089aed2018-10-25 21:33:57 -0700956
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800957template <typename SourceVariant>
958void RenderEngineTest::fillBufferLayerTransform() {
959 fillBufferWithLayerTransform<SourceVariant>();
Alec Mouri1089aed2018-10-25 21:33:57 -0700960 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 0, 0);
961 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
962 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
963 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
964 255, 0, 0, 255);
965}
966
967template <typename SourceVariant>
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800968void RenderEngineTest::fillBufferWithColorTransform() {
Alec Mouri1089aed2018-10-25 21:33:57 -0700969 renderengine::DisplaySettings settings;
970 settings.physicalDisplay = fullscreenRect();
971 settings.clip = Rect(1, 1);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800972 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700973
Sally Qi59a9f502021-10-12 18:53:23 +0000974 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700975
976 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800977 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700978 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800979 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700980 layer.alpha = 1.0f;
981
982 // construct a fake color matrix
983 // annihilate green and blue channels
KaiChieh Chuang436fc192020-09-07 13:48:42 +0800984 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
Alec Mouri1089aed2018-10-25 21:33:57 -0700985 // set red channel to red + green
986 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
987
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800988 layer.alpha = 1.0f;
989 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
990
Sally Qi59a9f502021-10-12 18:53:23 +0000991 layers.push_back(layer);
Alec Mouri1089aed2018-10-25 21:33:57 -0700992
Alec Mouric0aae732021-01-12 13:32:18 -0800993 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800994}
Alec Mouri1089aed2018-10-25 21:33:57 -0700995
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800996template <typename SourceVariant>
Sally Qi2019fd22021-11-22 10:19:04 -0800997void RenderEngineTest::fillBufferWithColorTransformAndSourceDataspace(
998 const ui::Dataspace sourceDataspace) {
999 renderengine::DisplaySettings settings;
1000 settings.physicalDisplay = fullscreenRect();
1001 settings.clip = Rect(1, 1);
1002 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1003
1004 std::vector<renderengine::LayerSettings> layers;
1005
1006 renderengine::LayerSettings layer;
1007 layer.sourceDataspace = sourceDataspace;
1008 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1009 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
1010 layer.alpha = 1.0f;
1011
1012 // construct a fake color matrix
1013 // annihilate green and blue channels
1014 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
1015 // set red channel to red + green
1016 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
1017
1018 layer.alpha = 1.0f;
1019 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1020
1021 layers.push_back(layer);
1022
1023 invokeDraw(settings, layers);
1024}
1025
1026template <typename SourceVariant>
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001027void RenderEngineTest::fillBufferColorTransform() {
1028 fillBufferWithColorTransform<SourceVariant>();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08001029 expectBufferColor(fullscreenRect(), 172, 0, 0, 255, 1);
1030}
1031
1032template <typename SourceVariant>
Sally Qi2019fd22021-11-22 10:19:04 -08001033void RenderEngineTest::fillBufferColorTransformAndSourceDataspace() {
1034 unordered_map<ui::Dataspace, ubyte4> dataspaceToColorMap;
1035 dataspaceToColorMap[ui::Dataspace::V0_BT709] = {172, 0, 0, 255};
1036 dataspaceToColorMap[ui::Dataspace::BT2020] = {172, 0, 0, 255};
1037 dataspaceToColorMap[ui::Dataspace::ADOBE_RGB] = {172, 0, 0, 255};
1038 ui::Dataspace customizedDataspace = static_cast<ui::Dataspace>(
1039 ui::Dataspace::STANDARD_BT709 | ui::Dataspace::TRANSFER_GAMMA2_2 |
1040 ui::Dataspace::RANGE_FULL);
1041 dataspaceToColorMap[customizedDataspace] = {172, 0, 0, 255};
1042 for (const auto& [sourceDataspace, color] : dataspaceToColorMap) {
1043 fillBufferWithColorTransformAndSourceDataspace<SourceVariant>(sourceDataspace);
1044 expectBufferColor(fullscreenRect(), color.r, color.g, color.b, color.a, 1);
1045 }
1046}
1047
1048template <typename SourceVariant>
1049void RenderEngineTest::fillBufferWithColorTransformAndOutputDataspace(
1050 const ui::Dataspace outputDataspace) {
1051 renderengine::DisplaySettings settings;
1052 settings.physicalDisplay = fullscreenRect();
1053 settings.clip = Rect(1, 1);
1054 settings.outputDataspace = outputDataspace;
1055
1056 std::vector<renderengine::LayerSettings> layers;
1057
1058 renderengine::LayerSettings layer;
1059 layer.sourceDataspace = ui::Dataspace::V0_SCRGB_LINEAR;
1060 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1061 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
1062 layer.alpha = 1.0f;
1063
1064 // construct a fake color matrix
1065 // annihilate green and blue channels
1066 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
1067 // set red channel to red + green
1068 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
1069
1070 layer.alpha = 1.0f;
1071 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1072
1073 layers.push_back(layer);
1074
1075 invokeDraw(settings, layers);
1076}
1077
1078template <typename SourceVariant>
1079void RenderEngineTest::fillBufferColorTransformAndOutputDataspace() {
1080 unordered_map<ui::Dataspace, ubyte4> dataspaceToColorMap;
1081 dataspaceToColorMap[ui::Dataspace::V0_BT709] = {202, 0, 0, 255};
1082 dataspaceToColorMap[ui::Dataspace::BT2020] = {192, 0, 0, 255};
1083 dataspaceToColorMap[ui::Dataspace::ADOBE_RGB] = {202, 0, 0, 255};
1084 ui::Dataspace customizedDataspace = static_cast<ui::Dataspace>(
1085 ui::Dataspace::STANDARD_BT709 | ui::Dataspace::TRANSFER_GAMMA2_6 |
1086 ui::Dataspace::RANGE_FULL);
1087 dataspaceToColorMap[customizedDataspace] = {202, 0, 0, 255};
1088 for (const auto& [outputDataspace, color] : dataspaceToColorMap) {
1089 fillBufferWithColorTransformAndOutputDataspace<SourceVariant>(outputDataspace);
1090 expectBufferColor(fullscreenRect(), color.r, color.g, color.b, color.a, 1);
1091 }
1092}
1093
1094template <typename SourceVariant>
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001095void RenderEngineTest::fillBufferWithColorTransformZeroLayerAlpha() {
1096 renderengine::DisplaySettings settings;
1097 settings.physicalDisplay = fullscreenRect();
1098 settings.clip = Rect(1, 1);
1099
Sally Qi59a9f502021-10-12 18:53:23 +00001100 std::vector<renderengine::LayerSettings> layers;
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001101
1102 renderengine::LayerSettings layer;
1103 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1104 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
1105 layer.alpha = 0;
1106
1107 // construct a fake color matrix
1108 // simple inverse color
1109 settings.colorTransform = mat4(-1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 1, 1, 1, 1);
1110
1111 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1112
Sally Qi59a9f502021-10-12 18:53:23 +00001113 layers.push_back(layer);
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001114
Alec Mouric0aae732021-01-12 13:32:18 -08001115 invokeDraw(settings, layers);
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001116}
1117
1118template <typename SourceVariant>
1119void RenderEngineTest::fillBufferColorTransformZeroLayerAlpha() {
1120 fillBufferWithColorTransformZeroLayerAlpha<SourceVariant>();
1121 expectBufferColor(fullscreenRect(), 0, 0, 0, 0);
1122}
1123
1124template <typename SourceVariant>
Alec Mouri7c94edb2018-12-03 21:23:26 -08001125void RenderEngineTest::fillRedBufferWithRoundedCorners() {
1126 renderengine::DisplaySettings settings;
1127 settings.physicalDisplay = fullscreenRect();
1128 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001129 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri7c94edb2018-12-03 21:23:26 -08001130
Sally Qi59a9f502021-10-12 18:53:23 +00001131 std::vector<renderengine::LayerSettings> layers;
Alec Mouri7c94edb2018-12-03 21:23:26 -08001132
1133 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001134 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri7c94edb2018-12-03 21:23:26 -08001135 layer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07001136 layer.geometry.roundedCornersRadius = {5.0f, 5.0f};
Alec Mouri7c94edb2018-12-03 21:23:26 -08001137 layer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
1138 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
1139 layer.alpha = 1.0f;
1140
Sally Qi59a9f502021-10-12 18:53:23 +00001141 layers.push_back(layer);
Alec Mouri7c94edb2018-12-03 21:23:26 -08001142
Alec Mouric0aae732021-01-12 13:32:18 -08001143 invokeDraw(settings, layers);
Alec Mouri7c94edb2018-12-03 21:23:26 -08001144}
1145
1146template <typename SourceVariant>
1147void RenderEngineTest::fillBufferWithRoundedCorners() {
1148 fillRedBufferWithRoundedCorners<SourceVariant>();
1149 // Corners should be ignored...
1150 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 0);
1151 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, 0, DEFAULT_DISPLAY_WIDTH, 1), 0, 0, 0, 0);
1152 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT - 1, 1, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
1153 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1,
1154 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1155 0, 0, 0, 0);
1156 // ...And the non-rounded portion should be red.
1157 // Other pixels may be anti-aliased, so let's not check those.
1158 expectBufferColor(Rect(5, 5, DEFAULT_DISPLAY_WIDTH - 5, DEFAULT_DISPLAY_HEIGHT - 5), 255, 0, 0,
1159 255);
1160}
1161
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001162template <typename SourceVariant>
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001163void RenderEngineTest::fillBufferAndBlurBackground() {
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001164 auto blurRadius = 50;
1165 auto center = DEFAULT_DISPLAY_WIDTH / 2;
1166
1167 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001168 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001169 settings.physicalDisplay = fullscreenRect();
1170 settings.clip = fullscreenRect();
1171
Sally Qi59a9f502021-10-12 18:53:23 +00001172 std::vector<renderengine::LayerSettings> layers;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001173
1174 renderengine::LayerSettings backgroundLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001175 backgroundLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001176 backgroundLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1177 SourceVariant::fillColor(backgroundLayer, 0.0f, 1.0f, 0.0f, this);
1178 backgroundLayer.alpha = 1.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001179 layers.emplace_back(backgroundLayer);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001180
1181 renderengine::LayerSettings leftLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001182 leftLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001183 leftLayer.geometry.boundaries =
1184 Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT).toFloatRect();
1185 SourceVariant::fillColor(leftLayer, 1.0f, 0.0f, 0.0f, this);
1186 leftLayer.alpha = 1.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001187 layers.emplace_back(leftLayer);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001188
1189 renderengine::LayerSettings blurLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001190 blurLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001191 blurLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1192 blurLayer.backgroundBlurRadius = blurRadius;
Derek Sollenbergerecb21462021-01-29 16:53:49 -05001193 SourceVariant::fillColor(blurLayer, 0.0f, 0.0f, 1.0f, this);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001194 blurLayer.alpha = 0;
Sally Qi59a9f502021-10-12 18:53:23 +00001195 layers.emplace_back(blurLayer);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001196
Alec Mouric0aae732021-01-12 13:32:18 -08001197 invokeDraw(settings, layers);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001198
Derek Sollenbergerecb21462021-01-29 16:53:49 -05001199 // solid color
1200 expectBufferColor(Rect(0, 0, 1, 1), 255, 0, 0, 255, 0 /* tolerance */);
1201
Derek Sollenbergerb3998372021-02-16 15:16:56 -05001202 if (mRE->supportsBackgroundBlur()) {
1203 // blurred color (downsampling should result in the center color being close to 128)
1204 expectBufferColor(Rect(center - 1, center - 5, center + 1, center + 5), 128, 128, 0, 255,
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001205 50 /* tolerance */);
Derek Sollenbergerb3998372021-02-16 15:16:56 -05001206 }
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001207}
1208
1209template <typename SourceVariant>
Alec Mourie8489fd2021-04-29 16:08:56 -07001210void RenderEngineTest::fillSmallLayerAndBlurBackground() {
1211 auto blurRadius = 50;
1212 renderengine::DisplaySettings settings;
1213 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1214 settings.physicalDisplay = fullscreenRect();
1215 settings.clip = fullscreenRect();
1216
Sally Qi59a9f502021-10-12 18:53:23 +00001217 std::vector<renderengine::LayerSettings> layers;
Alec Mourie8489fd2021-04-29 16:08:56 -07001218
1219 renderengine::LayerSettings backgroundLayer;
1220 backgroundLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1221 backgroundLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1222 SourceVariant::fillColor(backgroundLayer, 1.0f, 0.0f, 0.0f, this);
1223 backgroundLayer.alpha = 1.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001224 layers.push_back(backgroundLayer);
Alec Mourie8489fd2021-04-29 16:08:56 -07001225
1226 renderengine::LayerSettings blurLayer;
1227 blurLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1228 blurLayer.geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f);
1229 blurLayer.backgroundBlurRadius = blurRadius;
1230 SourceVariant::fillColor(blurLayer, 0.0f, 0.0f, 1.0f, this);
1231 blurLayer.alpha = 0;
Sally Qi59a9f502021-10-12 18:53:23 +00001232 layers.push_back(blurLayer);
Alec Mourie8489fd2021-04-29 16:08:56 -07001233
1234 invokeDraw(settings, layers);
1235
1236 // Give a generous tolerance - the blur rectangle is very small and this test is
1237 // mainly concerned with ensuring that there's no device failure.
1238 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT), 255, 0, 0, 255,
1239 40 /* tolerance */);
1240}
1241
1242template <typename SourceVariant>
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001243void RenderEngineTest::overlayCorners() {
1244 renderengine::DisplaySettings settings;
1245 settings.physicalDisplay = fullscreenRect();
1246 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001247 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001248
Sally Qi59a9f502021-10-12 18:53:23 +00001249 std::vector<renderengine::LayerSettings> layersFirst;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001250
1251 renderengine::LayerSettings layerOne;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001252 layerOne.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001253 layerOne.geometry.boundaries =
1254 FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH / 3.0, DEFAULT_DISPLAY_HEIGHT / 3.0);
1255 SourceVariant::fillColor(layerOne, 1.0f, 0.0f, 0.0f, this);
1256 layerOne.alpha = 0.2;
1257
Sally Qi59a9f502021-10-12 18:53:23 +00001258 layersFirst.push_back(layerOne);
Alec Mouric0aae732021-01-12 13:32:18 -08001259 invokeDraw(settings, layersFirst);
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001260 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3), 51, 0, 0, 51);
1261 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3 + 1, DEFAULT_DISPLAY_HEIGHT / 3 + 1,
1262 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1263 0, 0, 0, 0);
1264
Sally Qi59a9f502021-10-12 18:53:23 +00001265 std::vector<renderengine::LayerSettings> layersSecond;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001266 renderengine::LayerSettings layerTwo;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001267 layerTwo.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001268 layerTwo.geometry.boundaries =
1269 FloatRect(DEFAULT_DISPLAY_WIDTH / 3.0, DEFAULT_DISPLAY_HEIGHT / 3.0,
1270 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT);
1271 SourceVariant::fillColor(layerTwo, 0.0f, 1.0f, 0.0f, this);
1272 layerTwo.alpha = 1.0f;
1273
Sally Qi59a9f502021-10-12 18:53:23 +00001274 layersSecond.push_back(layerTwo);
Alec Mouric0aae732021-01-12 13:32:18 -08001275 invokeDraw(settings, layersSecond);
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001276
1277 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3), 0, 0, 0, 0);
1278 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3 + 1, DEFAULT_DISPLAY_HEIGHT / 3 + 1,
1279 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1280 0, 255, 0, 255);
1281}
1282
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001283void RenderEngineTest::fillRedBufferTextureTransform() {
1284 renderengine::DisplaySettings settings;
1285 settings.physicalDisplay = fullscreenRect();
1286 settings.clip = Rect(1, 1);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001287 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001288
Sally Qi59a9f502021-10-12 18:53:23 +00001289 std::vector<renderengine::LayerSettings> layers;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001290
1291 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001292 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001293 // Here will allocate a checker board texture, but transform texture
1294 // coordinates so that only the upper left is applied.
Alec Mouria90a5702021-04-16 16:36:21 +00001295 const auto buf = allocateSourceBuffer(2, 2);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001296 uint32_t texName;
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001297 RenderEngineTest::mRE->genTextures(1, &texName);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001298 this->mTexNames.push_back(texName);
1299
1300 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00001301 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1302 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001303 // Red top left, Green top right, Blue bottom left, Black bottom right
1304 pixels[0] = 255;
1305 pixels[1] = 0;
1306 pixels[2] = 0;
1307 pixels[3] = 255;
1308 pixels[4] = 0;
1309 pixels[5] = 255;
1310 pixels[6] = 0;
1311 pixels[7] = 255;
1312 pixels[8] = 0;
1313 pixels[9] = 0;
1314 pixels[10] = 255;
1315 pixels[11] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00001316 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001317
1318 layer.source.buffer.buffer = buf;
1319 layer.source.buffer.textureName = texName;
1320 // Transform coordinates to only be inside the red quadrant.
Alec Mouri4049b532021-10-15 20:59:33 -07001321 layer.source.buffer.textureTransform = mat4::scale(vec4(0.2f, 0.2f, 1.f, 1.f));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001322 layer.alpha = 1.0f;
1323 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1324
Sally Qi59a9f502021-10-12 18:53:23 +00001325 layers.push_back(layer);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001326
Alec Mouric0aae732021-01-12 13:32:18 -08001327 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001328}
1329
1330void RenderEngineTest::fillBufferTextureTransform() {
1331 fillRedBufferTextureTransform();
1332 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
1333}
1334
1335void RenderEngineTest::fillRedBufferWithPremultiplyAlpha() {
1336 renderengine::DisplaySettings settings;
1337 settings.physicalDisplay = fullscreenRect();
1338 // Here logical space is 1x1
1339 settings.clip = Rect(1, 1);
1340
Sally Qi59a9f502021-10-12 18:53:23 +00001341 std::vector<renderengine::LayerSettings> layers;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001342
1343 renderengine::LayerSettings layer;
Alec Mouria90a5702021-04-16 16:36:21 +00001344 const auto buf = allocateSourceBuffer(1, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001345 uint32_t texName;
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001346 RenderEngineTest::mRE->genTextures(1, &texName);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001347 this->mTexNames.push_back(texName);
1348
1349 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00001350 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1351 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001352 pixels[0] = 255;
1353 pixels[1] = 0;
1354 pixels[2] = 0;
1355 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00001356 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001357
1358 layer.source.buffer.buffer = buf;
1359 layer.source.buffer.textureName = texName;
1360 layer.source.buffer.usePremultipliedAlpha = true;
1361 layer.alpha = 0.5f;
1362 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1363
Sally Qi59a9f502021-10-12 18:53:23 +00001364 layers.push_back(layer);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001365
Alec Mouric0aae732021-01-12 13:32:18 -08001366 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001367}
1368
1369void RenderEngineTest::fillBufferWithPremultiplyAlpha() {
1370 fillRedBufferWithPremultiplyAlpha();
1371 expectBufferColor(fullscreenRect(), 128, 0, 0, 128);
1372}
1373
1374void RenderEngineTest::fillRedBufferWithoutPremultiplyAlpha() {
1375 renderengine::DisplaySettings settings;
1376 settings.physicalDisplay = fullscreenRect();
1377 // Here logical space is 1x1
1378 settings.clip = Rect(1, 1);
1379
Sally Qi59a9f502021-10-12 18:53:23 +00001380 std::vector<renderengine::LayerSettings> layers;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001381
1382 renderengine::LayerSettings layer;
Alec Mouria90a5702021-04-16 16:36:21 +00001383 const auto buf = allocateSourceBuffer(1, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001384 uint32_t texName;
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001385 RenderEngineTest::mRE->genTextures(1, &texName);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001386 this->mTexNames.push_back(texName);
1387
1388 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00001389 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1390 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001391 pixels[0] = 255;
1392 pixels[1] = 0;
1393 pixels[2] = 0;
1394 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00001395 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001396
1397 layer.source.buffer.buffer = buf;
1398 layer.source.buffer.textureName = texName;
1399 layer.source.buffer.usePremultipliedAlpha = false;
1400 layer.alpha = 0.5f;
1401 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1402
Sally Qi59a9f502021-10-12 18:53:23 +00001403 layers.push_back(layer);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001404
Alec Mouric0aae732021-01-12 13:32:18 -08001405 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001406}
1407
1408void RenderEngineTest::fillBufferWithoutPremultiplyAlpha() {
1409 fillRedBufferWithoutPremultiplyAlpha();
wukui16f3c0bb2020-08-05 20:35:29 +08001410 expectBufferColor(fullscreenRect(), 128, 0, 0, 128, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001411}
1412
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001413template <typename SourceVariant>
1414void RenderEngineTest::drawShadow(const renderengine::LayerSettings& castingLayer,
1415 const renderengine::ShadowSettings& shadow,
1416 const ubyte4& casterColor, const ubyte4& backgroundColor) {
1417 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001418 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001419 settings.physicalDisplay = fullscreenRect();
1420 settings.clip = fullscreenRect();
1421
Sally Qi59a9f502021-10-12 18:53:23 +00001422 std::vector<renderengine::LayerSettings> layers;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001423
1424 // add background layer
1425 renderengine::LayerSettings bgLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001426 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001427 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1428 ColorSourceVariant::fillColor(bgLayer, backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1429 backgroundColor.b / 255.0f, this);
1430 bgLayer.alpha = backgroundColor.a / 255.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001431 layers.push_back(bgLayer);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001432
1433 // add shadow layer
1434 renderengine::LayerSettings shadowLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001435 shadowLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001436 shadowLayer.geometry.boundaries = castingLayer.geometry.boundaries;
1437 shadowLayer.alpha = castingLayer.alpha;
1438 shadowLayer.shadow = shadow;
Sally Qi59a9f502021-10-12 18:53:23 +00001439 layers.push_back(shadowLayer);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001440
1441 // add layer casting the shadow
1442 renderengine::LayerSettings layer = castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001443 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001444 SourceVariant::fillColor(layer, casterColor.r / 255.0f, casterColor.g / 255.0f,
1445 casterColor.b / 255.0f, this);
Sally Qi59a9f502021-10-12 18:53:23 +00001446 layers.push_back(layer);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001447
Alec Mouric0aae732021-01-12 13:32:18 -08001448 invokeDraw(settings, layers);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001449}
1450
Alec Mouribd17b3b2020-12-17 11:08:30 -08001451void RenderEngineTest::drawShadowWithoutCaster(const FloatRect& castingBounds,
1452 const renderengine::ShadowSettings& shadow,
1453 const ubyte4& backgroundColor) {
1454 renderengine::DisplaySettings settings;
1455 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1456 settings.physicalDisplay = fullscreenRect();
1457 settings.clip = fullscreenRect();
1458
Sally Qi59a9f502021-10-12 18:53:23 +00001459 std::vector<renderengine::LayerSettings> layers;
Alec Mouribd17b3b2020-12-17 11:08:30 -08001460
1461 // add background layer
1462 renderengine::LayerSettings bgLayer;
1463 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1464 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1465 ColorSourceVariant::fillColor(bgLayer, backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1466 backgroundColor.b / 255.0f, this);
1467 bgLayer.alpha = backgroundColor.a / 255.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001468 layers.push_back(bgLayer);
Alec Mouribd17b3b2020-12-17 11:08:30 -08001469
1470 // add shadow layer
1471 renderengine::LayerSettings shadowLayer;
1472 shadowLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1473 shadowLayer.geometry.boundaries = castingBounds;
Derek Sollenbergerc31985e2021-05-18 16:38:17 -04001474 shadowLayer.skipContentDraw = true;
Alec Mouribd17b3b2020-12-17 11:08:30 -08001475 shadowLayer.alpha = 1.0f;
1476 ColorSourceVariant::fillColor(shadowLayer, 0, 0, 0, this);
1477 shadowLayer.shadow = shadow;
Sally Qi59a9f502021-10-12 18:53:23 +00001478 layers.push_back(shadowLayer);
Alec Mouribd17b3b2020-12-17 11:08:30 -08001479
Alec Mouric0aae732021-01-12 13:32:18 -08001480 invokeDraw(settings, layers);
Alec Mouribd17b3b2020-12-17 11:08:30 -08001481}
1482
Alec Mouri5a493722022-01-26 16:43:02 -08001483void RenderEngineTest::tonemap(ui::Dataspace sourceDataspace, std::function<vec3(vec3)> eotf,
1484 std::function<vec3(vec3, float)> scaleOotf) {
1485 constexpr int32_t kGreyLevels = 256;
1486
1487 const auto rect = Rect(0, 0, kGreyLevels, 1);
1488
1489 constexpr float kMaxLuminance = 750.f;
1490 constexpr float kCurrentLuminanceNits = 500.f;
1491 const renderengine::DisplaySettings display{
1492 .physicalDisplay = rect,
1493 .clip = rect,
1494 .maxLuminance = kMaxLuminance,
1495 .currentLuminanceNits = kCurrentLuminanceNits,
1496 .outputDataspace = ui::Dataspace::DISPLAY_P3,
1497 };
1498
1499 auto buf = std::make_shared<
1500 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07001501 ExternalTexture>(sp<GraphicBuffer>::make(kGreyLevels, 1,
1502 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1503 GRALLOC_USAGE_SW_READ_OFTEN |
1504 GRALLOC_USAGE_SW_WRITE_OFTEN |
1505 GRALLOC_USAGE_HW_RENDER |
1506 GRALLOC_USAGE_HW_TEXTURE,
1507 "input"),
Alec Mouri5a493722022-01-26 16:43:02 -08001508 *mRE,
1509 renderengine::impl::ExternalTexture::Usage::READABLE |
1510 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
1511 ASSERT_EQ(0, buf->getBuffer()->initCheck());
1512 {
1513 uint8_t* pixels;
1514 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1515 reinterpret_cast<void**>(&pixels));
1516
1517 uint8_t color = 0;
1518 for (int32_t j = 0; j < buf->getBuffer()->getHeight(); j++) {
1519 uint8_t* dest = pixels + (buf->getBuffer()->getStride() * j * 4);
1520 for (int32_t i = 0; i < buf->getBuffer()->getWidth(); i++) {
1521 dest[0] = color;
1522 dest[1] = color;
1523 dest[2] = color;
1524 dest[3] = 255;
1525 color++;
1526 dest += 4;
1527 }
1528 }
1529 buf->getBuffer()->unlock();
1530 }
1531
1532 mBuffer = std::make_shared<
1533 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07001534 ExternalTexture>(sp<GraphicBuffer>::make(kGreyLevels, 1,
1535 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1536 GRALLOC_USAGE_SW_READ_OFTEN |
1537 GRALLOC_USAGE_SW_WRITE_OFTEN |
1538 GRALLOC_USAGE_HW_RENDER |
1539 GRALLOC_USAGE_HW_TEXTURE,
1540 "output"),
Alec Mouri5a493722022-01-26 16:43:02 -08001541 *mRE,
1542 renderengine::impl::ExternalTexture::Usage::READABLE |
1543 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
1544 ASSERT_EQ(0, mBuffer->getBuffer()->initCheck());
1545
1546 const renderengine::LayerSettings layer{.geometry.boundaries = rect.toFloatRect(),
1547 .source =
1548 renderengine::PixelSource{
1549 .buffer =
1550 renderengine::Buffer{
1551 .buffer =
1552 std::move(buf),
1553 .usePremultipliedAlpha =
1554 true,
1555 },
1556 },
1557 .alpha = 1.0f,
1558 .sourceDataspace = sourceDataspace};
1559
1560 std::vector<renderengine::LayerSettings> layers{layer};
1561 invokeDraw(display, layers);
1562
1563 ColorSpace displayP3 = ColorSpace::DisplayP3();
1564 ColorSpace bt2020 = ColorSpace::BT2020();
1565
1566 tonemap::Metadata metadata{.displayMaxLuminance = 750.0f};
1567
1568 auto generator = [=](Point location) {
1569 const double normColor = static_cast<double>(location.x) / (kGreyLevels - 1);
1570 const vec3 rgb = vec3(normColor, normColor, normColor);
1571
1572 const vec3 linearRGB = eotf(rgb);
1573
1574 const vec3 xyz = bt2020.getRGBtoXYZ() * linearRGB;
1575
1576 const vec3 scaledXYZ = scaleOotf(xyz, kCurrentLuminanceNits);
Alec Mouri196b0f22022-03-04 22:13:48 +00001577 const auto gains =
Alec Mouri5a493722022-01-26 16:43:02 -08001578 tonemap::getToneMapper()
1579 ->lookupTonemapGain(static_cast<aidl::android::hardware::graphics::common::
1580 Dataspace>(sourceDataspace),
1581 static_cast<aidl::android::hardware::graphics::common::
1582 Dataspace>(
1583 ui::Dataspace::DISPLAY_P3),
Alec Mouri196b0f22022-03-04 22:13:48 +00001584 {tonemap::
1585 Color{.linearRGB =
1586 scaleOotf(linearRGB,
1587 kCurrentLuminanceNits),
1588 .xyz = scaledXYZ}},
Alec Mouri5a493722022-01-26 16:43:02 -08001589 metadata);
Alec Mouri196b0f22022-03-04 22:13:48 +00001590 EXPECT_EQ(1, gains.size());
1591 const double gain = gains.front();
Alec Mouri5a493722022-01-26 16:43:02 -08001592 const vec3 normalizedXYZ = scaledXYZ * gain / metadata.displayMaxLuminance;
1593
1594 const vec3 targetRGB = OETF_sRGB(displayP3.getXYZtoRGB() * normalizedXYZ) * 255;
1595 return ubyte4(static_cast<uint8_t>(targetRGB.r), static_cast<uint8_t>(targetRGB.g),
1596 static_cast<uint8_t>(targetRGB.b), 255);
1597 };
1598
1599 expectBufferColor(Rect(kGreyLevels, 1), generator, 2);
1600}
1601
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001602INSTANTIATE_TEST_SUITE_P(PerRenderEngineType, RenderEngineTest,
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001603 testing::Values(std::make_shared<GLESRenderEngineFactory>(),
Alec Mouri0eab3e82020-12-08 18:10:27 -08001604 std::make_shared<GLESCMRenderEngineFactory>(),
1605 std::make_shared<SkiaGLESRenderEngineFactory>(),
1606 std::make_shared<SkiaGLESCMRenderEngineFactory>()));
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001607
1608TEST_P(RenderEngineTest, drawLayers_noLayersToDraw) {
Alec Mouric0aae732021-01-12 13:32:18 -08001609 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001610 drawEmptyLayers();
1611}
1612
Sally Qi1fed86e2022-06-23 15:33:52 -07001613TEST_P(RenderEngineTest, drawLayers_fillRedBufferAndEmptyBuffer) {
1614 const auto& renderEngineFactory = GetParam();
1615 if (renderEngineFactory->type() == renderengine::RenderEngine::RenderEngineType::GLES) {
1616 // GLES-specific test
1617 return;
1618 }
1619
1620 initializeRenderEngine();
1621 renderengine::DisplaySettings settings;
1622 settings.physicalDisplay = fullscreenRect();
1623 settings.clip = fullscreenRect();
1624 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1625
1626 // add a red layer
1627 renderengine::LayerSettings layerOne{
1628 .geometry.boundaries = fullscreenRect().toFloatRect(),
1629 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
1630 .alpha = 1.f,
1631 };
1632
1633 std::vector<renderengine::LayerSettings> layersFirst{layerOne};
1634 invokeDraw(settings, layersFirst);
1635 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
1636
1637 // re-draw with an empty layer above it, and we get a transparent black one
1638 std::vector<renderengine::LayerSettings> layersSecond;
1639 invokeDraw(settings, layersSecond);
1640 expectBufferColor(fullscreenRect(), 0, 0, 0, 0);
1641}
1642
Ana Krulec07b98df2021-01-07 14:38:40 -08001643TEST_P(RenderEngineTest, drawLayers_withoutBuffers_withColorTransform) {
Alec Mouria90a5702021-04-16 16:36:21 +00001644 initializeRenderEngine();
Ana Krulec07b98df2021-01-07 14:38:40 -08001645
1646 renderengine::DisplaySettings settings;
1647 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1648 settings.physicalDisplay = fullscreenRect();
1649 settings.clip = fullscreenRect();
1650
1651 // 255, 255, 255, 255 is full opaque white.
Alec Mouri4049b532021-10-15 20:59:33 -07001652 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
1653 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Ana Krulec07b98df2021-01-07 14:38:40 -08001654 // Create layer with given color.
1655 renderengine::LayerSettings bgLayer;
1656 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1657 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1658 bgLayer.source.solidColor = half3(backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1659 backgroundColor.b / 255.0f);
1660 bgLayer.alpha = backgroundColor.a / 255.0f;
1661 // Transform the red color.
1662 bgLayer.colorTransform = mat4(-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
1663
Sally Qi59a9f502021-10-12 18:53:23 +00001664 std::vector<renderengine::LayerSettings> layers;
1665 layers.push_back(bgLayer);
Ana Krulec07b98df2021-01-07 14:38:40 -08001666
Alec Mouric0aae732021-01-12 13:32:18 -08001667 invokeDraw(settings, layers);
Ana Krulec07b98df2021-01-07 14:38:40 -08001668
1669 // Expect to see full opaque pixel (with inverted red from the transform).
Alec Mouric0aae732021-01-12 13:32:18 -08001670 expectBufferColor(Rect(0, 0, 10, 10), 0.f, backgroundColor.g, backgroundColor.b,
Ana Krulec07b98df2021-01-07 14:38:40 -08001671 backgroundColor.a);
1672}
1673
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001674TEST_P(RenderEngineTest, drawLayers_nullOutputBuffer) {
Alec Mouric0aae732021-01-12 13:32:18 -08001675 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001676
Alec Mourid43ccab2019-03-13 12:23:45 -07001677 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001678 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Sally Qi59a9f502021-10-12 18:53:23 +00001679 std::vector<renderengine::LayerSettings> layers;
Alec Mourid43ccab2019-03-13 12:23:45 -07001680 renderengine::LayerSettings layer;
1681 layer.geometry.boundaries = fullscreenRect().toFloatRect();
1682 BufferSourceVariant<ForceOpaqueBufferVariant>::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
Sally Qi59a9f502021-10-12 18:53:23 +00001683 layers.push_back(layer);
Sally Qi4cabdd02021-08-05 16:45:57 -07001684 std::future<renderengine::RenderEngineResult> result =
1685 mRE->drawLayers(settings, layers, nullptr, true, base::unique_fd());
Alec Mourid43ccab2019-03-13 12:23:45 -07001686
Sally Qi4cabdd02021-08-05 16:45:57 -07001687 ASSERT_TRUE(result.valid());
Derek Sollenbergerec411212021-08-25 10:54:47 -04001688 auto [status, fence] = result.get();
Alec Mourid43ccab2019-03-13 12:23:45 -07001689 ASSERT_EQ(BAD_VALUE, status);
Derek Sollenbergerec411212021-08-25 10:54:47 -04001690 ASSERT_FALSE(fence.ok());
Alec Mourid43ccab2019-03-13 12:23:45 -07001691}
1692
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001693TEST_P(RenderEngineTest, drawLayers_doesNotCacheFramebuffer) {
1694 const auto& renderEngineFactory = GetParam();
Alec Mouric0aae732021-01-12 13:32:18 -08001695
1696 if (renderEngineFactory->type() != renderengine::RenderEngine::RenderEngineType::GLES) {
1697 // GLES-specific test
1698 return;
1699 }
1700
1701 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001702
Alec Mourife0d72b2019-03-21 14:05:56 -07001703 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001704 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourife0d72b2019-03-21 14:05:56 -07001705 settings.physicalDisplay = fullscreenRect();
1706 settings.clip = fullscreenRect();
1707
Sally Qi59a9f502021-10-12 18:53:23 +00001708 std::vector<renderengine::LayerSettings> layers;
Alec Mourife0d72b2019-03-21 14:05:56 -07001709 renderengine::LayerSettings layer;
1710 layer.geometry.boundaries = fullscreenRect().toFloatRect();
1711 BufferSourceVariant<ForceOpaqueBufferVariant>::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
1712 layer.alpha = 1.0;
Sally Qi59a9f502021-10-12 18:53:23 +00001713 layers.push_back(layer);
Alec Mourife0d72b2019-03-21 14:05:56 -07001714
Sally Qi4cabdd02021-08-05 16:45:57 -07001715 std::future<renderengine::RenderEngineResult> result =
1716 mRE->drawLayers(settings, layers, mBuffer, false, base::unique_fd());
1717 ASSERT_TRUE(result.valid());
Derek Sollenbergerec411212021-08-25 10:54:47 -04001718 auto [status, fence] = result.get();
1719
Alec Mourife0d72b2019-03-21 14:05:56 -07001720 ASSERT_EQ(NO_ERROR, status);
Derek Sollenbergerec411212021-08-25 10:54:47 -04001721 if (fence.ok()) {
1722 sync_wait(fence.get(), -1);
1723 }
1724
Alec Mouria90a5702021-04-16 16:36:21 +00001725 ASSERT_FALSE(mGLESRE->isFramebufferImageCachedForTesting(mBuffer->getBuffer()->getId()));
Alec Mourife0d72b2019-03-21 14:05:56 -07001726 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
1727}
1728
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001729TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001730 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001731 fillRedBuffer<ColorSourceVariant>();
1732}
1733
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001734TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001735 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001736 fillGreenBuffer<ColorSourceVariant>();
1737}
1738
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001739TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001740 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001741 fillBlueBuffer<ColorSourceVariant>();
1742}
1743
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001744TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001745 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001746 fillRedTransparentBuffer<ColorSourceVariant>();
1747}
1748
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001749TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001750 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001751 fillBufferPhysicalOffset<ColorSourceVariant>();
1752}
1753
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001754TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001755 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001756 fillBufferCheckersRotate0<ColorSourceVariant>();
1757}
1758
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001759TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001760 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001761 fillBufferCheckersRotate90<ColorSourceVariant>();
1762}
1763
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001764TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001765 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001766 fillBufferCheckersRotate180<ColorSourceVariant>();
1767}
1768
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001769TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001770 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001771 fillBufferCheckersRotate270<ColorSourceVariant>();
1772}
1773
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001774TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001775 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001776 fillBufferLayerTransform<ColorSourceVariant>();
1777}
1778
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001779TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001780 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08001781 fillBufferColorTransform<ColorSourceVariant>();
1782}
1783
Sally Qi2019fd22021-11-22 10:19:04 -08001784TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_sourceDataspace) {
1785 const auto& renderEngineFactory = GetParam();
1786 // skip for non color management
1787 if (!renderEngineFactory->useColorManagement()) {
1788 return;
1789 }
1790 // skip for GLESRenderEngine
1791 if (renderEngineFactory->type() != renderengine::RenderEngine::RenderEngineType::GLES) {
1792 return;
1793 }
1794
1795 initializeRenderEngine();
1796 fillBufferColorTransformAndSourceDataspace<ColorSourceVariant>();
1797}
1798
1799TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_outputDataspace) {
1800 const auto& renderEngineFactory = GetParam();
1801 // skip for non color management
1802 if (!renderEngineFactory->useColorManagement()) {
1803 return;
1804 }
1805 // skip for GLESRenderEngine
1806 if (renderEngineFactory->type() != renderengine::RenderEngine::RenderEngineType::GLES) {
1807 return;
1808 }
1809
1810 initializeRenderEngine();
1811 fillBufferColorTransformAndOutputDataspace<ColorSourceVariant>();
1812}
1813
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001814TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001815 initializeRenderEngine();
Alec Mouri7c94edb2018-12-03 21:23:26 -08001816 fillBufferWithRoundedCorners<ColorSourceVariant>();
1817}
1818
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001819TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001820 initializeRenderEngine();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001821 fillBufferColorTransformZeroLayerAlpha<ColorSourceVariant>();
1822}
1823
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001824TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001825 initializeRenderEngine();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001826 fillBufferAndBlurBackground<ColorSourceVariant>();
1827}
1828
Alec Mourie8489fd2021-04-29 16:08:56 -07001829TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_colorSource) {
1830 initializeRenderEngine();
1831 fillSmallLayerAndBlurBackground<ColorSourceVariant>();
1832}
1833
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001834TEST_P(RenderEngineTest, drawLayers_overlayCorners_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001835 initializeRenderEngine();
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001836 overlayCorners<ColorSourceVariant>();
1837}
1838
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001839TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001840 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001841 fillRedBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1842}
1843
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001844TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001845 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001846 fillGreenBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1847}
1848
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001849TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001850 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001851 fillBlueBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1852}
1853
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001854TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001855 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001856 fillRedTransparentBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1857}
1858
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001859TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001860 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001861 fillBufferPhysicalOffset<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1862}
1863
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001864TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001865 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001866 fillBufferCheckersRotate0<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1867}
1868
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001869TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001870 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001871 fillBufferCheckersRotate90<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1872}
1873
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001874TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001875 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001876 fillBufferCheckersRotate180<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1877}
1878
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001879TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001880 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001881 fillBufferCheckersRotate270<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1882}
1883
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001884TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001885 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001886 fillBufferLayerTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1887}
1888
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001889TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001890 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08001891 fillBufferColorTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1892}
1893
Sally Qi2019fd22021-11-22 10:19:04 -08001894TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndSourceDataspace_opaqueBufferSource) {
1895 const auto& renderEngineFactory = GetParam();
1896 // skip for non color management
1897 if (!renderEngineFactory->useColorManagement()) {
1898 return;
1899 }
1900 // skip for GLESRenderEngine
1901 if (renderEngineFactory->type() != renderengine::RenderEngine::RenderEngineType::GLES) {
1902 return;
1903 }
1904
1905 initializeRenderEngine();
1906 fillBufferColorTransformAndSourceDataspace<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1907}
1908
1909TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndOutputDataspace_opaqueBufferSource) {
1910 const auto& renderEngineFactory = GetParam();
1911 // skip for non color management
1912 if (!renderEngineFactory->useColorManagement()) {
1913 return;
1914 }
1915 // skip for GLESRenderEngine
1916 if (renderEngineFactory->type() != renderengine::RenderEngine::RenderEngineType::GLES) {
1917 return;
1918 }
1919
1920 initializeRenderEngine();
1921 fillBufferColorTransformAndOutputDataspace<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1922}
1923
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001924TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001925 initializeRenderEngine();
Alec Mouri7c94edb2018-12-03 21:23:26 -08001926 fillBufferWithRoundedCorners<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1927}
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001928
Alec Mouric0aae732021-01-12 13:32:18 -08001929TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_opaqueBufferSource) {
1930 initializeRenderEngine();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001931 fillBufferColorTransformZeroLayerAlpha<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1932}
Alec Mouri7c94edb2018-12-03 21:23:26 -08001933
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001934TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001935 initializeRenderEngine();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001936 fillBufferAndBlurBackground<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1937}
1938
Alec Mourie8489fd2021-04-29 16:08:56 -07001939TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_opaqueBufferSource) {
1940 initializeRenderEngine();
1941 fillSmallLayerAndBlurBackground<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1942}
1943
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001944TEST_P(RenderEngineTest, drawLayers_overlayCorners_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001945 initializeRenderEngine();
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001946 overlayCorners<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1947}
1948
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001949TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001950 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001951 fillRedBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1952}
1953
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001954TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001955 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001956 fillGreenBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1957}
1958
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001959TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001960 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001961 fillBlueBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1962}
1963
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001964TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001965 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001966 fillRedTransparentBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1967}
1968
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001969TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001970 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001971 fillBufferPhysicalOffset<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1972}
1973
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001974TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001975 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001976 fillBufferCheckersRotate0<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1977}
1978
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001979TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001980 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001981 fillBufferCheckersRotate90<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1982}
1983
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001984TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001985 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001986 fillBufferCheckersRotate180<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1987}
1988
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001989TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001990 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001991 fillBufferCheckersRotate270<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1992}
1993
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001994TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001995 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001996 fillBufferLayerTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1997}
1998
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001999TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08002000 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08002001 fillBufferColorTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2002}
2003
Sally Qi2019fd22021-11-22 10:19:04 -08002004TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndSourceDataspace_bufferSource) {
2005 const auto& renderEngineFactory = GetParam();
2006 // skip for non color management
2007 if (!renderEngineFactory->useColorManagement()) {
2008 return;
2009 }
2010 // skip for GLESRenderEngine
2011 if (renderEngineFactory->type() != renderengine::RenderEngine::RenderEngineType::GLES) {
2012 return;
2013 }
2014
2015 initializeRenderEngine();
2016 fillBufferColorTransformAndSourceDataspace<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2017}
2018
2019TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndOutputDataspace_bufferSource) {
2020 const auto& renderEngineFactory = GetParam();
2021 // skip for non color management
2022 if (!renderEngineFactory->useColorManagement()) {
2023 return;
2024 }
2025 // skip for GLESRenderEngine
2026 if (renderEngineFactory->type() != renderengine::RenderEngine::RenderEngineType::GLES) {
2027 return;
2028 }
2029
2030 initializeRenderEngine();
2031 fillBufferColorTransformAndOutputDataspace<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2032}
2033
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002034TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08002035 initializeRenderEngine();
Alec Mouri7c94edb2018-12-03 21:23:26 -08002036 fillBufferWithRoundedCorners<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2037}
2038
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08002039TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08002040 initializeRenderEngine();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08002041 fillBufferColorTransformZeroLayerAlpha<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2042}
2043
Nathaniel Nifong53494f32021-04-30 14:05:39 -04002044TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08002045 initializeRenderEngine();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08002046 fillBufferAndBlurBackground<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2047}
2048
Alec Mourie8489fd2021-04-29 16:08:56 -07002049TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_bufferSource) {
2050 initializeRenderEngine();
2051 fillSmallLayerAndBlurBackground<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2052}
2053
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002054TEST_P(RenderEngineTest, drawLayers_overlayCorners_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08002055 initializeRenderEngine();
Alec Mourie7d1d4a2019-02-05 01:13:46 +00002056 overlayCorners<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2057}
2058
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002059TEST_P(RenderEngineTest, drawLayers_fillBufferTextureTransform) {
Alec Mouric0aae732021-01-12 13:32:18 -08002060 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002061 fillBufferTextureTransform();
2062}
2063
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002064TEST_P(RenderEngineTest, drawLayers_fillBuffer_premultipliesAlpha) {
Alec Mouric0aae732021-01-12 13:32:18 -08002065 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002066 fillBufferWithPremultiplyAlpha();
2067}
2068
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002069TEST_P(RenderEngineTest, drawLayers_fillBuffer_withoutPremultiplyingAlpha) {
Alec Mouric0aae732021-01-12 13:32:18 -08002070 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002071 fillBufferWithoutPremultiplyAlpha();
2072}
2073
Alec Mouribd17b3b2020-12-17 11:08:30 -08002074TEST_P(RenderEngineTest, drawLayers_fillShadow_castsWithoutCasterLayer) {
Alec Mouric0aae732021-01-12 13:32:18 -08002075 initializeRenderEngine();
Alec Mouribd17b3b2020-12-17 11:08:30 -08002076
Alec Mouri4049b532021-10-15 20:59:33 -07002077 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2078 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Alec Mouribd17b3b2020-12-17 11:08:30 -08002079 const float shadowLength = 5.0f;
2080 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2081 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2082 renderengine::ShadowSettings settings =
2083 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2084 false /* casterIsTranslucent */);
2085
2086 drawShadowWithoutCaster(casterBounds.toFloatRect(), settings, backgroundColor);
2087 expectShadowColorWithoutCaster(casterBounds.toFloatRect(), settings, backgroundColor);
2088}
2089
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002090TEST_P(RenderEngineTest, drawLayers_fillShadow_casterLayerMinSize) {
Alec Mouric0aae732021-01-12 13:32:18 -08002091 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002092
Alec Mouri4049b532021-10-15 20:59:33 -07002093 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2094 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2095 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2096 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002097 const float shadowLength = 5.0f;
2098 Rect casterBounds(1, 1);
2099 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2100 renderengine::LayerSettings castingLayer;
2101 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2102 castingLayer.alpha = 1.0f;
2103 renderengine::ShadowSettings settings =
2104 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2105 false /* casterIsTranslucent */);
2106
2107 drawShadow<ColorSourceVariant>(castingLayer, settings, casterColor, backgroundColor);
2108 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2109}
2110
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002111TEST_P(RenderEngineTest, drawLayers_fillShadow_casterColorLayer) {
Alec Mouric0aae732021-01-12 13:32:18 -08002112 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002113
Alec Mouri4049b532021-10-15 20:59:33 -07002114 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2115 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2116 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2117 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002118 const float shadowLength = 5.0f;
2119 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2120 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2121 renderengine::LayerSettings castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002122 castingLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002123 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2124 castingLayer.alpha = 1.0f;
2125 renderengine::ShadowSettings settings =
2126 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2127 false /* casterIsTranslucent */);
2128
2129 drawShadow<ColorSourceVariant>(castingLayer, settings, casterColor, backgroundColor);
2130 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2131}
2132
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002133TEST_P(RenderEngineTest, drawLayers_fillShadow_casterOpaqueBufferLayer) {
Alec Mouric0aae732021-01-12 13:32:18 -08002134 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002135
Alec Mouri4049b532021-10-15 20:59:33 -07002136 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2137 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2138 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2139 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002140 const float shadowLength = 5.0f;
2141 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2142 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2143 renderengine::LayerSettings castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002144 castingLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002145 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2146 castingLayer.alpha = 1.0f;
2147 renderengine::ShadowSettings settings =
2148 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2149 false /* casterIsTranslucent */);
2150
2151 drawShadow<BufferSourceVariant<ForceOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2152 backgroundColor);
2153 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2154}
2155
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002156TEST_P(RenderEngineTest, drawLayers_fillShadow_casterWithRoundedCorner) {
Alec Mouric0aae732021-01-12 13:32:18 -08002157 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002158
Alec Mouri4049b532021-10-15 20:59:33 -07002159 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2160 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2161 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2162 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002163 const float shadowLength = 5.0f;
2164 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2165 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2166 renderengine::LayerSettings castingLayer;
2167 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002168 castingLayer.geometry.roundedCornersRadius = {3.0f, 3.0f};
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002169 castingLayer.geometry.roundedCornersCrop = casterBounds.toFloatRect();
2170 castingLayer.alpha = 1.0f;
2171 renderengine::ShadowSettings settings =
2172 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2173 false /* casterIsTranslucent */);
2174
2175 drawShadow<BufferSourceVariant<ForceOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2176 backgroundColor);
2177 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2178}
2179
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002180TEST_P(RenderEngineTest, drawLayers_fillShadow_translucentCasterWithAlpha) {
Alec Mouric0aae732021-01-12 13:32:18 -08002181 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002182
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002183 const ubyte4 casterColor(255, 0, 0, 255);
2184 const ubyte4 backgroundColor(255, 255, 255, 255);
2185 const float shadowLength = 5.0f;
2186 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2187 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2188 renderengine::LayerSettings castingLayer;
2189 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2190 castingLayer.alpha = 0.5f;
2191 renderengine::ShadowSettings settings =
2192 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2193 true /* casterIsTranslucent */);
2194
2195 drawShadow<BufferSourceVariant<RelaxOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2196 backgroundColor);
2197
2198 // verify only the background since the shadow will draw behind the caster
2199 const float shadowInset = settings.length * -1.0f;
2200 const Rect casterWithShadow =
2201 Rect(casterBounds).inset(shadowInset, shadowInset, shadowInset, shadowInset);
2202 const Region backgroundRegion = Region(fullscreenRect()).subtractSelf(casterWithShadow);
2203 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
2204 backgroundColor.a);
2205}
2206
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002207TEST_P(RenderEngineTest, cleanupPostRender_cleansUpOnce) {
Alec Mouric0aae732021-01-12 13:32:18 -08002208 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002209
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002210 renderengine::DisplaySettings settings;
2211 settings.physicalDisplay = fullscreenRect();
2212 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002213 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002214
Sally Qi59a9f502021-10-12 18:53:23 +00002215 std::vector<renderengine::LayerSettings> layers;
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002216 renderengine::LayerSettings layer;
2217 layer.geometry.boundaries = fullscreenRect().toFloatRect();
2218 BufferSourceVariant<ForceOpaqueBufferVariant>::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
2219 layer.alpha = 1.0;
Sally Qi59a9f502021-10-12 18:53:23 +00002220 layers.push_back(layer);
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002221
Sally Qi4cabdd02021-08-05 16:45:57 -07002222 std::future<renderengine::RenderEngineResult> resultOne =
2223 mRE->drawLayers(settings, layers, mBuffer, true, base::unique_fd());
2224 ASSERT_TRUE(resultOne.valid());
2225 auto [statusOne, fenceOne] = resultOne.get();
2226 ASSERT_EQ(NO_ERROR, statusOne);
2227
2228 std::future<renderengine::RenderEngineResult> resultTwo =
2229 mRE->drawLayers(settings, layers, mBuffer, true, std::move(fenceOne));
2230 ASSERT_TRUE(resultTwo.valid());
2231 auto [statusTwo, fenceTwo] = resultTwo.get();
2232 ASSERT_EQ(NO_ERROR, statusTwo);
Derek Sollenbergerec411212021-08-25 10:54:47 -04002233 if (fenceTwo.ok()) {
2234 sync_wait(fenceTwo.get(), -1);
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002235 }
Derek Sollenbergerec411212021-08-25 10:54:47 -04002236
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002237 // Only cleanup the first time.
Derek Sollenbergerd3f60652021-06-11 15:34:36 -04002238 EXPECT_FALSE(mRE->canSkipPostRenderCleanup());
2239 mRE->cleanupPostRender();
2240 EXPECT_TRUE(mRE->canSkipPostRenderCleanup());
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002241}
2242
Ana Krulecf9a15d92020-12-11 08:35:00 -08002243TEST_P(RenderEngineTest, testRoundedCornersCrop) {
Alec Mouric0aae732021-01-12 13:32:18 -08002244 initializeRenderEngine();
Ana Krulecf9a15d92020-12-11 08:35:00 -08002245
2246 renderengine::DisplaySettings settings;
2247 settings.physicalDisplay = fullscreenRect();
2248 settings.clip = fullscreenRect();
2249 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2250
Sally Qi59a9f502021-10-12 18:53:23 +00002251 std::vector<renderengine::LayerSettings> layers;
Ana Krulecf9a15d92020-12-11 08:35:00 -08002252
2253 renderengine::LayerSettings redLayer;
2254 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2255 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002256 redLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
2257
Ana Krulecf9a15d92020-12-11 08:35:00 -08002258 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2259 // Red background.
2260 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2261 redLayer.alpha = 1.0f;
2262
Sally Qi59a9f502021-10-12 18:53:23 +00002263 layers.push_back(redLayer);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002264
2265 // Green layer with 1/3 size.
2266 renderengine::LayerSettings greenLayer;
2267 greenLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2268 greenLayer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002269 greenLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
Ana Krulecf9a15d92020-12-11 08:35:00 -08002270 // Bottom right corner is not going to be rounded.
2271 greenLayer.geometry.roundedCornersCrop =
2272 Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3, DEFAULT_DISPLAY_HEIGHT,
2273 DEFAULT_DISPLAY_HEIGHT)
2274 .toFloatRect();
2275 greenLayer.source.solidColor = half3(0.0f, 1.0f, 0.0f);
2276 greenLayer.alpha = 1.0f;
2277
Sally Qi59a9f502021-10-12 18:53:23 +00002278 layers.push_back(greenLayer);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002279
Alec Mouric0aae732021-01-12 13:32:18 -08002280 invokeDraw(settings, layers);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002281
2282 // Corners should be ignored...
2283 // Screen size: width is 128, height is 256.
2284 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 0);
2285 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, 0, DEFAULT_DISPLAY_WIDTH, 1), 0, 0, 0, 0);
2286 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT - 1, 1, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
2287 // Bottom right corner is kept out of the clipping, and it's green.
2288 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1,
2289 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
2290 0, 255, 0, 255);
2291}
2292
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002293TEST_P(RenderEngineTest, testRoundedCornersParentCrop) {
2294 initializeRenderEngine();
2295
2296 renderengine::DisplaySettings settings;
2297 settings.physicalDisplay = fullscreenRect();
2298 settings.clip = fullscreenRect();
2299 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2300
Sally Qi59a9f502021-10-12 18:53:23 +00002301 std::vector<renderengine::LayerSettings> layers;
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002302
2303 renderengine::LayerSettings redLayer;
2304 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2305 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002306 redLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002307 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2308 // Red background.
2309 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2310 redLayer.alpha = 1.0f;
2311
Sally Qi59a9f502021-10-12 18:53:23 +00002312 layers.push_back(redLayer);
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002313
2314 // Green layer with 1/2 size with parent crop rect.
2315 renderengine::LayerSettings greenLayer = redLayer;
2316 greenLayer.geometry.boundaries =
2317 FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT / 2);
2318 greenLayer.source.solidColor = half3(0.0f, 1.0f, 0.0f);
2319
Sally Qi59a9f502021-10-12 18:53:23 +00002320 layers.push_back(greenLayer);
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002321
2322 invokeDraw(settings, layers);
2323
2324 // Due to roundedCornersRadius, the corners are untouched.
2325 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2326 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2327 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2328 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2329
2330 // top middle should be green and the bottom middle red
2331 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, 0), 0, 255, 0, 255);
2332 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0, 255);
2333
2334 // the bottom edge of the green layer should not be rounded
2335 expectBufferColor(Point(0, (DEFAULT_DISPLAY_HEIGHT / 2) - 1), 0, 255, 0, 255);
2336}
2337
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002338TEST_P(RenderEngineTest, testRoundedCornersParentCropSmallBounds) {
2339 initializeRenderEngine();
2340
2341 renderengine::DisplaySettings settings;
2342 settings.physicalDisplay = fullscreenRect();
2343 settings.clip = fullscreenRect();
2344 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2345
Sally Qi59a9f502021-10-12 18:53:23 +00002346 std::vector<renderengine::LayerSettings> layers;
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002347
2348 renderengine::LayerSettings redLayer;
2349 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2350 redLayer.geometry.boundaries = FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, 32);
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002351 redLayer.geometry.roundedCornersRadius = {64.0f, 64.0f};
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002352 redLayer.geometry.roundedCornersCrop = FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, 128);
2353 // Red background.
2354 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2355 redLayer.alpha = 1.0f;
2356
Sally Qi59a9f502021-10-12 18:53:23 +00002357 layers.push_back(redLayer);
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002358 invokeDraw(settings, layers);
2359
2360 // Due to roundedCornersRadius, the top corners are untouched.
2361 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2362 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2363
2364 // ensure that the entire height of the red layer was clipped by the rounded corners crop.
2365 expectBufferColor(Point(0, 31), 0, 0, 0, 0);
2366 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 31), 0, 0, 0, 0);
2367
2368 // the bottom middle should be red
2369 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, 31), 255, 0, 0, 255);
2370}
2371
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002372TEST_P(RenderEngineTest, testRoundedCornersXY) {
2373 if (GetParam()->type() != renderengine::RenderEngine::RenderEngineType::SKIA_GL) {
2374 GTEST_SKIP();
2375 }
2376
2377 initializeRenderEngine();
2378
2379 renderengine::DisplaySettings settings;
2380 settings.physicalDisplay = fullscreenRect();
2381 settings.clip = fullscreenRect();
2382 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2383
2384 std::vector<renderengine::LayerSettings> layers;
2385
2386 renderengine::LayerSettings redLayer;
2387 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2388 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
2389 redLayer.geometry.roundedCornersRadius = {5.0f, 20.0f};
2390 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2391 // Red background.
2392 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2393 redLayer.alpha = 1.0f;
2394
2395 layers.push_back(redLayer);
2396
2397 invokeDraw(settings, layers);
2398
2399 // Due to roundedCornersRadius, the corners are untouched.
2400 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2401 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2402 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2403 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2404
2405 // Y-axis draws a larger radius, check that its untouched as well
2406 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 5), 0, 0, 0, 0);
2407 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 5), 0, 0, 0, 0);
2408 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 5), 0, 0, 0, 0);
2409 expectBufferColor(Point(0, 5), 0, 0, 0, 0);
2410
2411 // middle should be red
2412 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0, 255);
2413}
2414
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002415TEST_P(RenderEngineTest, testClear) {
2416 initializeRenderEngine();
2417
2418 const auto rect = fullscreenRect();
2419 const renderengine::DisplaySettings display{
2420 .physicalDisplay = rect,
2421 .clip = rect,
2422 };
2423
2424 const renderengine::LayerSettings redLayer{
2425 .geometry.boundaries = rect.toFloatRect(),
2426 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
2427 .alpha = 1.0f,
2428 };
2429
2430 // This mimics prepareClearClientComposition. This layer should overwrite
2431 // the redLayer, so that the buffer is transparent, rather than red.
2432 const renderengine::LayerSettings clearLayer{
2433 .geometry.boundaries = rect.toFloatRect(),
2434 .source.solidColor = half3(0.0f, 0.0f, 0.0f),
2435 .alpha = 0.0f,
2436 .disableBlending = true,
2437 };
2438
Sally Qi59a9f502021-10-12 18:53:23 +00002439 std::vector<renderengine::LayerSettings> layers{redLayer, clearLayer};
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002440 invokeDraw(display, layers);
2441 expectBufferColor(rect, 0, 0, 0, 0);
2442}
2443
2444TEST_P(RenderEngineTest, testDisableBlendingBuffer) {
2445 initializeRenderEngine();
2446
2447 const auto rect = Rect(0, 0, 1, 1);
2448 const renderengine::DisplaySettings display{
2449 .physicalDisplay = rect,
2450 .clip = rect,
2451 };
2452
2453 const renderengine::LayerSettings redLayer{
2454 .geometry.boundaries = rect.toFloatRect(),
2455 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
2456 .alpha = 1.0f,
2457 };
2458
2459 // The next layer will overwrite redLayer with a GraphicBuffer that is green
2460 // applied with a translucent alpha.
Alec Mouria90a5702021-04-16 16:36:21 +00002461 const auto buf = allocateSourceBuffer(1, 1);
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002462 {
2463 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00002464 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2465 reinterpret_cast<void**>(&pixels));
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002466 pixels[0] = 0;
2467 pixels[1] = 255;
2468 pixels[2] = 0;
2469 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00002470 buf->getBuffer()->unlock();
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002471 }
2472
2473 const renderengine::LayerSettings greenLayer{
2474 .geometry.boundaries = rect.toFloatRect(),
2475 .source =
2476 renderengine::PixelSource{
2477 .buffer =
2478 renderengine::Buffer{
2479 .buffer = buf,
2480 .usePremultipliedAlpha = true,
2481 },
2482 },
2483 .alpha = 0.5f,
2484 .disableBlending = true,
2485 };
2486
Sally Qi59a9f502021-10-12 18:53:23 +00002487 std::vector<renderengine::LayerSettings> layers{redLayer, greenLayer};
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002488 invokeDraw(display, layers);
2489 expectBufferColor(rect, 0, 128, 0, 128);
2490}
2491
Tianhao Yao67dd7122022-02-22 17:48:33 +00002492TEST_P(RenderEngineTest, testBorder) {
2493 if (GetParam()->type() != renderengine::RenderEngine::RenderEngineType::SKIA_GL) {
2494 GTEST_SKIP();
2495 }
2496
2497 if (!GetParam()->useColorManagement()) {
2498 GTEST_SKIP();
2499 }
2500
2501 initializeRenderEngine();
2502
2503 const ui::Dataspace dataspace = ui::Dataspace::V0_SRGB;
2504
2505 const auto displayRect = Rect(1080, 2280);
2506 renderengine::DisplaySettings display{
2507 .physicalDisplay = displayRect,
2508 .clip = displayRect,
2509 .outputDataspace = dataspace,
2510 };
2511 display.borderInfoList.clear();
2512 renderengine::BorderRenderInfo info;
2513 info.combinedRegion = Region(Rect(99, 99, 199, 199));
Tianhao Yao10cea3c2022-03-30 01:37:22 +00002514 info.width = 20.0f;
2515 info.color = half4{1.0f, 128.0f / 255.0f, 0.0f, 1.0f};
Tianhao Yao67dd7122022-02-22 17:48:33 +00002516 display.borderInfoList.emplace_back(info);
2517
2518 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2519 const renderengine::LayerSettings greenLayer{
2520 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2521 .source =
2522 renderengine::PixelSource{
2523 .buffer =
2524 renderengine::Buffer{
2525 .buffer = greenBuffer,
2526 .usePremultipliedAlpha = true,
2527 },
2528 },
2529 .alpha = 1.0f,
2530 .sourceDataspace = dataspace,
2531 .whitePointNits = 200.f,
2532 };
2533
2534 std::vector<renderengine::LayerSettings> layers;
2535 layers.emplace_back(greenLayer);
2536 invokeDraw(display, layers);
2537
2538 expectBufferColor(Rect(99, 99, 101, 101), 255, 128, 0, 255, 1);
2539}
2540
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002541TEST_P(RenderEngineTest, testDimming) {
2542 if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) {
Alec Mouri85065692022-03-18 00:58:26 +00002543 GTEST_SKIP();
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002544 }
Alec Mouri85065692022-03-18 00:58:26 +00002545
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002546 initializeRenderEngine();
2547
Alec Mouri85065692022-03-18 00:58:26 +00002548 const ui::Dataspace dataspace = ui::Dataspace::V0_SRGB_LINEAR;
2549
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002550 const auto displayRect = Rect(3, 1);
2551 const renderengine::DisplaySettings display{
2552 .physicalDisplay = displayRect,
2553 .clip = displayRect,
Alec Mouri85065692022-03-18 00:58:26 +00002554 .outputDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002555 .targetLuminanceNits = 1000.f,
2556 };
2557
2558 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2559 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2560 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2561
2562 const renderengine::LayerSettings greenLayer{
2563 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2564 .source =
2565 renderengine::PixelSource{
2566 .buffer =
2567 renderengine::Buffer{
2568 .buffer = greenBuffer,
2569 .usePremultipliedAlpha = true,
2570 },
2571 },
2572 .alpha = 1.0f,
Alec Mouri85065692022-03-18 00:58:26 +00002573 .sourceDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002574 .whitePointNits = 200.f,
2575 };
2576
2577 const renderengine::LayerSettings blueLayer{
2578 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2579 .source =
2580 renderengine::PixelSource{
2581 .buffer =
2582 renderengine::Buffer{
2583 .buffer = blueBuffer,
2584 .usePremultipliedAlpha = true,
2585 },
2586 },
2587 .alpha = 1.0f,
Alec Mouri85065692022-03-18 00:58:26 +00002588 .sourceDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002589 .whitePointNits = 1000.f / 51.f,
2590 };
2591
2592 const renderengine::LayerSettings redLayer{
2593 .geometry.boundaries = FloatRect(2.f, 0.f, 3.f, 1.f),
2594 .source =
2595 renderengine::PixelSource{
2596 .buffer =
2597 renderengine::Buffer{
2598 .buffer = redBuffer,
2599 .usePremultipliedAlpha = true,
2600 },
2601 },
2602 .alpha = 1.0f,
Alec Mouri85065692022-03-18 00:58:26 +00002603 .sourceDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002604 // When the white point is not set for a layer, just ignore it and treat it as the same
2605 // as the max layer
2606 .whitePointNits = -1.f,
2607 };
2608
2609 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer, redLayer};
2610 invokeDraw(display, layers);
2611
2612 expectBufferColor(Rect(1, 1), 0, 51, 0, 255, 1);
2613 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 5, 255, 1);
2614 expectBufferColor(Rect(2, 0, 3, 1), 51, 0, 0, 255, 1);
2615}
2616
Alec Mouri85065692022-03-18 00:58:26 +00002617TEST_P(RenderEngineTest, testDimming_inGammaSpace) {
2618 if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) {
2619 GTEST_SKIP();
2620 }
2621 initializeRenderEngine();
2622
2623 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2624 ui::Dataspace::TRANSFER_GAMMA2_2 |
2625 ui::Dataspace::RANGE_FULL);
2626
2627 const auto displayRect = Rect(3, 1);
2628 const renderengine::DisplaySettings display{
2629 .physicalDisplay = displayRect,
2630 .clip = displayRect,
2631 .outputDataspace = dataspace,
2632 .targetLuminanceNits = 1000.f,
2633 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2634 };
2635
2636 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2637 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2638 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2639
2640 const renderengine::LayerSettings greenLayer{
2641 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2642 .source =
2643 renderengine::PixelSource{
2644 .buffer =
2645 renderengine::Buffer{
2646 .buffer = greenBuffer,
2647 .usePremultipliedAlpha = true,
2648 },
2649 },
2650 .alpha = 1.0f,
2651 .sourceDataspace = dataspace,
2652 .whitePointNits = 200.f,
2653 };
2654
2655 const renderengine::LayerSettings blueLayer{
2656 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2657 .source =
2658 renderengine::PixelSource{
2659 .buffer =
2660 renderengine::Buffer{
2661 .buffer = blueBuffer,
2662 .usePremultipliedAlpha = true,
2663 },
2664 },
2665 .alpha = 1.0f,
2666 .sourceDataspace = dataspace,
2667 .whitePointNits = 1000.f / 51.f,
2668 };
2669
2670 const renderengine::LayerSettings redLayer{
2671 .geometry.boundaries = FloatRect(2.f, 0.f, 3.f, 1.f),
2672 .source =
2673 renderengine::PixelSource{
2674 .buffer =
2675 renderengine::Buffer{
2676 .buffer = redBuffer,
2677 .usePremultipliedAlpha = true,
2678 },
2679 },
2680 .alpha = 1.0f,
2681 .sourceDataspace = dataspace,
2682 // When the white point is not set for a layer, just ignore it and treat it as the same
2683 // as the max layer
2684 .whitePointNits = -1.f,
2685 };
2686
2687 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer, redLayer};
2688 invokeDraw(display, layers);
2689
2690 expectBufferColor(Rect(1, 1), 0, 122, 0, 255, 1);
2691 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 42, 255, 1);
2692 expectBufferColor(Rect(2, 0, 3, 1), 122, 0, 0, 255, 1);
2693}
2694
Alec Mouri9bcd1d12022-04-21 22:16:56 +00002695TEST_P(RenderEngineTest, testDimming_inGammaSpace_withDisplayColorTransform) {
2696 if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) {
2697 GTEST_SKIP();
2698 }
2699 initializeRenderEngine();
2700
2701 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2702 ui::Dataspace::TRANSFER_GAMMA2_2 |
2703 ui::Dataspace::RANGE_FULL);
2704
2705 const auto displayRect = Rect(3, 1);
2706 const renderengine::DisplaySettings display{
2707 .physicalDisplay = displayRect,
2708 .clip = displayRect,
2709 .outputDataspace = dataspace,
2710 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
2711 .targetLuminanceNits = 1000.f,
2712 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2713 };
2714
2715 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2716 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2717 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2718
2719 const renderengine::LayerSettings greenLayer{
2720 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2721 .source =
2722 renderengine::PixelSource{
2723 .buffer =
2724 renderengine::Buffer{
2725 .buffer = greenBuffer,
2726 .usePremultipliedAlpha = true,
2727 },
2728 },
2729 .alpha = 1.0f,
2730 .sourceDataspace = dataspace,
2731 .whitePointNits = 200.f,
2732 };
2733
2734 const renderengine::LayerSettings redLayer{
2735 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2736 .source =
2737 renderengine::PixelSource{
2738 .buffer =
2739 renderengine::Buffer{
2740 .buffer = redBuffer,
2741 .usePremultipliedAlpha = true,
2742 },
2743 },
2744 .alpha = 1.0f,
2745 .sourceDataspace = dataspace,
2746 // When the white point is not set for a layer, just ignore it and treat it as the same
2747 // as the max layer
2748 .whitePointNits = -1.f,
2749 };
2750
2751 std::vector<renderengine::LayerSettings> layers{greenLayer, redLayer};
2752 invokeDraw(display, layers);
2753
2754 expectBufferColor(Rect(1, 1), 0, 0, 0, 255, 1);
2755 expectBufferColor(Rect(1, 0, 2, 1), 0, 122, 0, 255, 1);
2756}
2757
2758TEST_P(RenderEngineTest, testDimming_inGammaSpace_withDisplayColorTransform_deviceHandles) {
2759 if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) {
2760 GTEST_SKIP();
2761 }
2762 initializeRenderEngine();
2763
2764 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2765 ui::Dataspace::TRANSFER_GAMMA2_2 |
2766 ui::Dataspace::RANGE_FULL);
2767
2768 const auto displayRect = Rect(3, 1);
2769 const renderengine::DisplaySettings display{
2770 .physicalDisplay = displayRect,
2771 .clip = displayRect,
2772 .outputDataspace = dataspace,
2773 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
2774 .deviceHandlesColorTransform = true,
2775 .targetLuminanceNits = 1000.f,
2776 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2777 };
2778
2779 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2780 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2781 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2782
2783 const renderengine::LayerSettings greenLayer{
2784 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2785 .source =
2786 renderengine::PixelSource{
2787 .buffer =
2788 renderengine::Buffer{
2789 .buffer = greenBuffer,
2790 .usePremultipliedAlpha = true,
2791 },
2792 },
2793 .alpha = 1.0f,
2794 .sourceDataspace = dataspace,
2795 .whitePointNits = 200.f,
2796 };
2797
2798 const renderengine::LayerSettings redLayer{
2799 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2800 .source =
2801 renderengine::PixelSource{
2802 .buffer =
2803 renderengine::Buffer{
2804 .buffer = redBuffer,
2805 .usePremultipliedAlpha = true,
2806 },
2807 },
2808 .alpha = 1.0f,
2809 .sourceDataspace = dataspace,
2810 // When the white point is not set for a layer, just ignore it and treat it as the same
2811 // as the max layer
2812 .whitePointNits = -1.f,
2813 };
2814
2815 std::vector<renderengine::LayerSettings> layers{greenLayer, redLayer};
2816 invokeDraw(display, layers);
2817
2818 expectBufferColor(Rect(1, 1), 0, 122, 0, 255, 1);
2819 expectBufferColor(Rect(1, 0, 2, 1), 122, 0, 0, 255, 1);
2820}
2821
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002822TEST_P(RenderEngineTest, testDimming_withoutTargetLuminance) {
2823 initializeRenderEngine();
2824 if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) {
2825 return;
2826 }
2827
2828 const auto displayRect = Rect(2, 1);
2829 const renderengine::DisplaySettings display{
2830 .physicalDisplay = displayRect,
2831 .clip = displayRect,
2832 .outputDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2833 .targetLuminanceNits = -1.f,
2834 };
2835
2836 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2837 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2838
2839 const renderengine::LayerSettings greenLayer{
2840 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2841 .source =
2842 renderengine::PixelSource{
2843 .buffer =
2844 renderengine::Buffer{
2845 .buffer = greenBuffer,
2846 .usePremultipliedAlpha = true,
2847 },
2848 },
2849 .alpha = 1.0f,
2850 .sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2851 .whitePointNits = 200.f,
2852 };
2853
2854 const renderengine::LayerSettings blueLayer{
2855 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2856 .source =
2857 renderengine::PixelSource{
2858 .buffer =
2859 renderengine::Buffer{
2860 .buffer = blueBuffer,
2861 .usePremultipliedAlpha = true,
2862 },
2863 },
2864 .alpha = 1.0f,
2865 .sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2866 .whitePointNits = 1000.f,
2867 };
2868
2869 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer};
2870 invokeDraw(display, layers);
2871
2872 expectBufferColor(Rect(1, 1), 0, 51, 0, 255, 1);
2873 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 255, 255);
2874}
2875
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002876TEST_P(RenderEngineTest, test_isOpaque) {
2877 initializeRenderEngine();
2878
2879 const auto rect = Rect(0, 0, 1, 1);
2880 const renderengine::DisplaySettings display{
2881 .physicalDisplay = rect,
2882 .clip = rect,
2883 .outputDataspace = ui::Dataspace::DISPLAY_P3,
2884 };
2885
2886 // Create an unpremul buffer that is green with no alpha. Using isOpaque
2887 // should make the green show.
2888 const auto buf = allocateSourceBuffer(1, 1);
2889 {
2890 uint8_t* pixels;
2891 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2892 reinterpret_cast<void**>(&pixels));
2893 pixels[0] = 0;
2894 pixels[1] = 255;
2895 pixels[2] = 0;
2896 pixels[3] = 0;
2897 buf->getBuffer()->unlock();
2898 }
2899
2900 const renderengine::LayerSettings greenLayer{
2901 .geometry.boundaries = rect.toFloatRect(),
2902 .source =
2903 renderengine::PixelSource{
2904 .buffer =
2905 renderengine::Buffer{
2906 .buffer = buf,
2907 // Although the pixels are not
2908 // premultiplied in practice, this
2909 // matches the input we see.
2910 .usePremultipliedAlpha = true,
2911 .isOpaque = true,
2912 },
2913 },
2914 .alpha = 1.0f,
2915 };
2916
Sally Qi59a9f502021-10-12 18:53:23 +00002917 std::vector<renderengine::LayerSettings> layers{greenLayer};
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002918 invokeDraw(display, layers);
2919
2920 if (GetParam()->useColorManagement()) {
2921 expectBufferColor(rect, 117, 251, 76, 255);
2922 } else {
2923 expectBufferColor(rect, 0, 255, 0, 255);
2924 }
2925}
Alec Mouri4049b532021-10-15 20:59:33 -07002926
Alec Mouri4049b532021-10-15 20:59:33 -07002927TEST_P(RenderEngineTest, test_tonemapPQMatches) {
2928 if (!GetParam()->useColorManagement()) {
Alec Mouri5a493722022-01-26 16:43:02 -08002929 GTEST_SKIP();
Alec Mouri4049b532021-10-15 20:59:33 -07002930 }
2931
2932 if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) {
Alec Mouri5a493722022-01-26 16:43:02 -08002933 GTEST_SKIP();
Alec Mouri4049b532021-10-15 20:59:33 -07002934 }
2935
2936 initializeRenderEngine();
2937
Alec Mouri5a493722022-01-26 16:43:02 -08002938 tonemap(
2939 static_cast<ui::Dataspace>(HAL_DATASPACE_STANDARD_BT2020 |
2940 HAL_DATASPACE_TRANSFER_ST2084 | HAL_DATASPACE_RANGE_FULL),
2941 [](vec3 color) { return EOTF_PQ(color); },
2942 [](vec3 color, float) {
2943 static constexpr float kMaxPQLuminance = 10000.f;
2944 return color * kMaxPQLuminance;
2945 });
2946}
Alec Mouri4049b532021-10-15 20:59:33 -07002947
Alec Mouri5a493722022-01-26 16:43:02 -08002948TEST_P(RenderEngineTest, test_tonemapHLGMatches) {
2949 if (!GetParam()->useColorManagement()) {
2950 GTEST_SKIP();
Alec Mouri4049b532021-10-15 20:59:33 -07002951 }
2952
Alec Mouri5a493722022-01-26 16:43:02 -08002953 if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) {
2954 GTEST_SKIP();
2955 }
Alec Mouri4049b532021-10-15 20:59:33 -07002956
Alec Mouri5a493722022-01-26 16:43:02 -08002957 initializeRenderEngine();
Alec Mouri4049b532021-10-15 20:59:33 -07002958
Alec Mouri5a493722022-01-26 16:43:02 -08002959 tonemap(
2960 static_cast<ui::Dataspace>(HAL_DATASPACE_STANDARD_BT2020 | HAL_DATASPACE_TRANSFER_HLG |
2961 HAL_DATASPACE_RANGE_FULL),
2962 [](vec3 color) { return EOTF_HLG(color); },
2963 [](vec3 color, float currentLuminaceNits) {
2964 static constexpr float kMaxHLGLuminance = 1000.f;
Alec Mouri7a577452022-03-04 23:41:38 +00002965 return color * kMaxHLGLuminance;
Alec Mouri5a493722022-01-26 16:43:02 -08002966 });
Alec Mouri4049b532021-10-15 20:59:33 -07002967}
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -05002968
2969TEST_P(RenderEngineTest, r8_behaves_as_mask) {
2970 if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) {
2971 return;
2972 }
2973
2974 initializeRenderEngine();
2975
2976 const auto r8Buffer = allocateR8Buffer(2, 1);
2977 if (!r8Buffer) {
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05002978 GTEST_SKIP() << "Test is only necessary on devices that support r8";
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -05002979 return;
2980 }
2981 {
2982 uint8_t* pixels;
2983 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2984 reinterpret_cast<void**>(&pixels));
2985 // This will be drawn on top of a green buffer. We'll verify that 255
2986 // results in keeping the original green and 0 results in black.
2987 pixels[0] = 0;
2988 pixels[1] = 255;
2989 r8Buffer->getBuffer()->unlock();
2990 }
2991
2992 const auto rect = Rect(0, 0, 2, 1);
2993 const renderengine::DisplaySettings display{
2994 .physicalDisplay = rect,
2995 .clip = rect,
2996 .outputDataspace = ui::Dataspace::SRGB,
2997 };
2998
2999 const auto greenBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(0, 255, 0, 255));
3000 const renderengine::LayerSettings greenLayer{
3001 .geometry.boundaries = rect.toFloatRect(),
3002 .source =
3003 renderengine::PixelSource{
3004 .buffer =
3005 renderengine::Buffer{
3006 .buffer = greenBuffer,
3007 },
3008 },
3009 .alpha = 1.0f,
3010 };
3011 const renderengine::LayerSettings r8Layer{
3012 .geometry.boundaries = rect.toFloatRect(),
3013 .source =
3014 renderengine::PixelSource{
3015 .buffer =
3016 renderengine::Buffer{
3017 .buffer = r8Buffer,
3018 },
3019 },
3020 .alpha = 1.0f,
3021 };
3022
3023 std::vector<renderengine::LayerSettings> layers{greenLayer, r8Layer};
3024 invokeDraw(display, layers);
3025
3026 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 255);
3027 expectBufferColor(Rect(1, 0, 2, 1), 0, 255, 0, 255);
3028}
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003029
3030TEST_P(RenderEngineTest, r8_respects_color_transform) {
3031 if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) {
3032 return;
3033 }
3034
3035 initializeRenderEngine();
3036
3037 const auto r8Buffer = allocateR8Buffer(2, 1);
3038 if (!r8Buffer) {
3039 GTEST_SKIP() << "Test is only necessary on devices that support r8";
3040 return;
3041 }
3042 {
3043 uint8_t* pixels;
3044 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
3045 reinterpret_cast<void**>(&pixels));
3046 pixels[0] = 0;
3047 pixels[1] = 255;
3048 r8Buffer->getBuffer()->unlock();
3049 }
3050
3051 const auto rect = Rect(0, 0, 2, 1);
3052 const renderengine::DisplaySettings display{
3053 .physicalDisplay = rect,
3054 .clip = rect,
3055 .outputDataspace = ui::Dataspace::SRGB,
3056 // Verify that the R8 layer respects the color transform when
3057 // deviceHandlesColorTransform is false. This transform converts
3058 // pure red to pure green. That will occur when the R8 buffer is
3059 // 255. When the R8 buffer is 0, it will still change to black, as
3060 // with r8_behaves_as_mask.
Alec Mouri9bcd1d12022-04-21 22:16:56 +00003061 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003062 .deviceHandlesColorTransform = false,
3063 };
3064
3065 const auto redBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(255, 0, 0, 255));
3066 const renderengine::LayerSettings redLayer{
3067 .geometry.boundaries = rect.toFloatRect(),
3068 .source =
3069 renderengine::PixelSource{
3070 .buffer =
3071 renderengine::Buffer{
3072 .buffer = redBuffer,
3073 },
3074 },
3075 .alpha = 1.0f,
3076 };
3077 const renderengine::LayerSettings r8Layer{
3078 .geometry.boundaries = rect.toFloatRect(),
3079 .source =
3080 renderengine::PixelSource{
3081 .buffer =
3082 renderengine::Buffer{
3083 .buffer = r8Buffer,
3084 },
3085 },
3086 .alpha = 1.0f,
3087 };
3088
3089 std::vector<renderengine::LayerSettings> layers{redLayer, r8Layer};
3090 invokeDraw(display, layers);
3091
3092 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 255);
3093 expectBufferColor(Rect(1, 0, 2, 1), 0, 255, 0, 255);
3094}
3095
3096TEST_P(RenderEngineTest, r8_respects_color_transform_when_device_handles) {
3097 if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) {
3098 return;
3099 }
3100
3101 initializeRenderEngine();
3102
3103 const auto r8Buffer = allocateR8Buffer(2, 1);
3104 if (!r8Buffer) {
3105 GTEST_SKIP() << "Test is only necessary on devices that support r8";
3106 return;
3107 }
3108 {
3109 uint8_t* pixels;
3110 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
3111 reinterpret_cast<void**>(&pixels));
3112 pixels[0] = 0;
3113 pixels[1] = 255;
3114 r8Buffer->getBuffer()->unlock();
3115 }
3116
3117 const auto rect = Rect(0, 0, 2, 1);
3118 const renderengine::DisplaySettings display{
3119 .physicalDisplay = rect,
3120 .clip = rect,
3121 .outputDataspace = ui::Dataspace::SRGB,
3122 // If deviceHandlesColorTransform is true, pixels where the A8
3123 // buffer is opaque are unaffected. If the colorTransform is
3124 // invertible, pixels where the A8 buffer are transparent have the
3125 // inverse applied to them so that the DPU will convert them back to
3126 // black. Test with an arbitrary, invertible matrix.
3127 .colorTransform = mat4(1, 0, 0, 2,
3128 3, 1, 2, 5,
3129 0, 5, 3, 0,
3130 0, 1, 0, 2),
3131 .deviceHandlesColorTransform = true,
3132 };
3133
3134 const auto redBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(255, 0, 0, 255));
3135 const renderengine::LayerSettings redLayer{
3136 .geometry.boundaries = rect.toFloatRect(),
3137 .source =
3138 renderengine::PixelSource{
3139 .buffer =
3140 renderengine::Buffer{
3141 .buffer = redBuffer,
3142 },
3143 },
3144 .alpha = 1.0f,
3145 };
3146 const renderengine::LayerSettings r8Layer{
3147 .geometry.boundaries = rect.toFloatRect(),
3148 .source =
3149 renderengine::PixelSource{
3150 .buffer =
3151 renderengine::Buffer{
3152 .buffer = r8Buffer,
3153 },
3154 },
3155 .alpha = 1.0f,
3156 };
3157
3158 std::vector<renderengine::LayerSettings> layers{redLayer, r8Layer};
3159 invokeDraw(display, layers);
3160
3161 expectBufferColor(Rect(1, 0, 2, 1), 255, 0, 0, 255); // Still red.
3162 expectBufferColor(Rect(0, 0, 1, 1), 0, 70, 0, 255);
3163}
Leon Scroggins III45be9182022-04-27 10:37:11 -04003164
3165TEST_P(RenderEngineTest, primeShaderCache) {
3166 if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) {
3167 GTEST_SKIP();
3168 }
3169
3170 initializeRenderEngine();
3171
3172 auto fut = mRE->primeCache();
3173 if (fut.valid()) {
3174 fut.wait();
3175 }
3176
3177 const int minimumExpectedShadersCompiled = GetParam()->useColorManagement() ? 60 : 30;
3178 ASSERT_GT(static_cast<skia::SkiaGLRenderEngine*>(mRE.get())->reportShadersCompiled(),
3179 minimumExpectedShadersCompiled);
3180}
Derek Sollenbergerd3f60652021-06-11 15:34:36 -04003181} // namespace renderengine
Alec Mouri6e57f682018-09-29 20:45:08 -07003182} // namespace android
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08003183
3184// TODO(b/129481165): remove the #pragma below and fix conversion issues
Marin Shalamanovbed7fd32020-12-21 20:02:20 +01003185#pragma clang diagnostic pop // ignored "-Wconversion -Wextra"