blob: add7a940de3d45c2816be1f8634ca890c1f37ce9 [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
94} // namespace
95
Ana Krulec82ba2ec2020-11-21 13:33:20 -080096class RenderEngineFactory {
97public:
98 virtual ~RenderEngineFactory() = default;
99
100 virtual std::string name() = 0;
Alec Mouric0aae732021-01-12 13:32:18 -0800101 virtual renderengine::RenderEngine::RenderEngineType type() = 0;
102 virtual std::unique_ptr<renderengine::RenderEngine> createRenderEngine() = 0;
103 virtual std::unique_ptr<renderengine::gl::GLESRenderEngine> createGLESRenderEngine() {
104 return nullptr;
105 }
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -0400106 virtual bool useColorManagement() const = 0;
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800107};
108
109class GLESRenderEngineFactory : public RenderEngineFactory {
110public:
111 std::string name() override { return "GLESRenderEngineFactory"; }
112
Alec Mouric0aae732021-01-12 13:32:18 -0800113 renderengine::RenderEngine::RenderEngineType type() {
114 return renderengine::RenderEngine::RenderEngineType::GLES;
115 }
116
117 std::unique_ptr<renderengine::RenderEngine> createRenderEngine() override {
118 return createGLESRenderEngine();
119 }
120
121 std::unique_ptr<renderengine::gl::GLESRenderEngine> createGLESRenderEngine() {
KaiChieh Chuang436fc192020-09-07 13:48:42 +0800122 renderengine::RenderEngineCreationArgs reCreationArgs =
Peiyong Lin4137a1d2019-10-09 10:39:09 -0700123 renderengine::RenderEngineCreationArgs::Builder()
Ana Krulec9bc9dc62020-02-26 12:16:40 -0800124 .setPixelFormat(static_cast<int>(ui::PixelFormat::RGBA_8888))
125 .setImageCacheSize(1)
126 .setUseColorManagerment(false)
127 .setEnableProtectedContext(false)
128 .setPrecacheToneMapperShaderOnly(false)
129 .setSupportsBackgroundBlur(true)
130 .setContextPriority(renderengine::RenderEngine::ContextPriority::MEDIUM)
Alec Mouric0aae732021-01-12 13:32:18 -0800131 .setRenderEngineType(type())
Alec Mourid2bcbae2021-06-28 17:02:17 -0700132 .setUseColorManagerment(useColorManagement())
KaiChieh Chuang436fc192020-09-07 13:48:42 +0800133 .build();
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800134 return renderengine::gl::GLESRenderEngine::create(reCreationArgs);
Alec Mourid43ccab2019-03-13 12:23:45 -0700135 }
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -0400136
137 bool useColorManagement() const override { return false; }
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800138};
Alec Mourid43ccab2019-03-13 12:23:45 -0700139
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800140class GLESCMRenderEngineFactory : public RenderEngineFactory {
141public:
142 std::string name() override { return "GLESCMRenderEngineFactory"; }
143
Alec Mouric0aae732021-01-12 13:32:18 -0800144 renderengine::RenderEngine::RenderEngineType type() {
145 return renderengine::RenderEngine::RenderEngineType::GLES;
146 }
147
148 std::unique_ptr<renderengine::RenderEngine> createRenderEngine() override {
149 return createGLESRenderEngine();
150 }
151
152 std::unique_ptr<renderengine::gl::GLESRenderEngine> createGLESRenderEngine() override {
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800153 renderengine::RenderEngineCreationArgs reCreationArgs =
154 renderengine::RenderEngineCreationArgs::Builder()
155 .setPixelFormat(static_cast<int>(ui::PixelFormat::RGBA_8888))
156 .setImageCacheSize(1)
157 .setEnableProtectedContext(false)
158 .setPrecacheToneMapperShaderOnly(false)
159 .setSupportsBackgroundBlur(true)
160 .setContextPriority(renderengine::RenderEngine::ContextPriority::MEDIUM)
Alec Mouric0aae732021-01-12 13:32:18 -0800161 .setRenderEngineType(type())
Alec Mourid2bcbae2021-06-28 17:02:17 -0700162 .setUseColorManagerment(useColorManagement())
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800163 .build();
164 return renderengine::gl::GLESRenderEngine::create(reCreationArgs);
165 }
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -0400166
167 bool useColorManagement() const override { return true; }
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800168};
169
Alec Mouri0eab3e82020-12-08 18:10:27 -0800170class SkiaGLESRenderEngineFactory : public RenderEngineFactory {
171public:
Alec Mouric0aae732021-01-12 13:32:18 -0800172 std::string name() override { return "SkiaGLRenderEngineFactory"; }
Alec Mouri0eab3e82020-12-08 18:10:27 -0800173
Alec Mouric0aae732021-01-12 13:32:18 -0800174 renderengine::RenderEngine::RenderEngineType type() {
175 return renderengine::RenderEngine::RenderEngineType::SKIA_GL;
176 }
177
178 std::unique_ptr<renderengine::RenderEngine> createRenderEngine() override {
Alec Mouri0eab3e82020-12-08 18:10:27 -0800179 renderengine::RenderEngineCreationArgs reCreationArgs =
180 renderengine::RenderEngineCreationArgs::Builder()
181 .setPixelFormat(static_cast<int>(ui::PixelFormat::RGBA_8888))
182 .setImageCacheSize(1)
183 .setEnableProtectedContext(false)
184 .setPrecacheToneMapperShaderOnly(false)
185 .setSupportsBackgroundBlur(true)
186 .setContextPriority(renderengine::RenderEngine::ContextPriority::MEDIUM)
Alec Mouric0aae732021-01-12 13:32:18 -0800187 .setRenderEngineType(type())
Alec Mourid2bcbae2021-06-28 17:02:17 -0700188 .setUseColorManagerment(useColorManagement())
Alec Mouri0eab3e82020-12-08 18:10:27 -0800189 .build();
Alec Mouric0aae732021-01-12 13:32:18 -0800190 return renderengine::skia::SkiaGLRenderEngine::create(reCreationArgs);
Alec Mouri0eab3e82020-12-08 18:10:27 -0800191 }
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -0400192
Alec Mourid2bcbae2021-06-28 17:02:17 -0700193 bool useColorManagement() const override { return false; }
Alec Mouri0eab3e82020-12-08 18:10:27 -0800194};
195
196class SkiaGLESCMRenderEngineFactory : public RenderEngineFactory {
197public:
Alec Mouric0aae732021-01-12 13:32:18 -0800198 std::string name() override { return "SkiaGLCMRenderEngineFactory"; }
Alec Mouri0eab3e82020-12-08 18:10:27 -0800199
Alec Mouric0aae732021-01-12 13:32:18 -0800200 renderengine::RenderEngine::RenderEngineType type() {
201 return renderengine::RenderEngine::RenderEngineType::SKIA_GL;
202 }
203
204 std::unique_ptr<renderengine::RenderEngine> createRenderEngine() override {
Alec Mouri0eab3e82020-12-08 18:10:27 -0800205 renderengine::RenderEngineCreationArgs reCreationArgs =
206 renderengine::RenderEngineCreationArgs::Builder()
207 .setPixelFormat(static_cast<int>(ui::PixelFormat::RGBA_8888))
208 .setImageCacheSize(1)
209 .setEnableProtectedContext(false)
210 .setPrecacheToneMapperShaderOnly(false)
211 .setSupportsBackgroundBlur(true)
212 .setContextPriority(renderengine::RenderEngine::ContextPriority::MEDIUM)
Alec Mouric0aae732021-01-12 13:32:18 -0800213 .setRenderEngineType(type())
Alec Mourid2bcbae2021-06-28 17:02:17 -0700214 .setUseColorManagerment(useColorManagement())
Alec Mouri0eab3e82020-12-08 18:10:27 -0800215 .build();
Alec Mouric0aae732021-01-12 13:32:18 -0800216 return renderengine::skia::SkiaGLRenderEngine::create(reCreationArgs);
Alec Mouri0eab3e82020-12-08 18:10:27 -0800217 }
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -0400218
219 bool useColorManagement() const override { return true; }
Alec Mouri0eab3e82020-12-08 18:10:27 -0800220};
221
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800222class RenderEngineTest : public ::testing::TestWithParam<std::shared_ptr<RenderEngineFactory>> {
223public:
Alec Mouria90a5702021-04-16 16:36:21 +0000224 std::shared_ptr<renderengine::ExternalTexture> allocateDefaultBuffer() {
225 return std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800226 renderengine::impl::
Alec Mouria90a5702021-04-16 16:36:21 +0000227 ExternalTexture>(new GraphicBuffer(DEFAULT_DISPLAY_WIDTH,
228 DEFAULT_DISPLAY_HEIGHT,
229 HAL_PIXEL_FORMAT_RGBA_8888, 1,
230 GRALLOC_USAGE_SW_READ_OFTEN |
231 GRALLOC_USAGE_SW_WRITE_OFTEN |
232 GRALLOC_USAGE_HW_RENDER |
233 GRALLOC_USAGE_HW_TEXTURE,
234 "output"),
235 *mRE,
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800236 renderengine::impl::ExternalTexture::Usage::READABLE |
237 renderengine::impl::ExternalTexture::Usage::
238 WRITEABLE);
Alec Mouri6e57f682018-09-29 20:45:08 -0700239 }
240
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800241 // Allocates a 1x1 buffer to fill with a solid color
Alec Mouria90a5702021-04-16 16:36:21 +0000242 std::shared_ptr<renderengine::ExternalTexture> allocateSourceBuffer(uint32_t width,
243 uint32_t height) {
244 return std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800245 renderengine::impl::
Alec Mouria90a5702021-04-16 16:36:21 +0000246 ExternalTexture>(new GraphicBuffer(width, height,
247 HAL_PIXEL_FORMAT_RGBA_8888, 1,
248 GRALLOC_USAGE_SW_READ_OFTEN |
249 GRALLOC_USAGE_SW_WRITE_OFTEN |
250 GRALLOC_USAGE_HW_TEXTURE,
251 "input"),
252 *mRE,
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800253 renderengine::impl::ExternalTexture::Usage::READABLE |
254 renderengine::impl::ExternalTexture::Usage::
255 WRITEABLE);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800256 }
257
Alec Mouricdf6cbc2021-11-01 17:21:15 -0700258 std::shared_ptr<renderengine::ExternalTexture> allocateAndFillSourceBuffer(uint32_t width,
259 uint32_t height,
260 ubyte4 color) {
261 const auto buffer = allocateSourceBuffer(width, height);
262 uint8_t* pixels;
263 buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
264 reinterpret_cast<void**>(&pixels));
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -0500265 for (uint32_t j = 0; j < height; j++) {
266 uint8_t* dst = pixels + (buffer->getBuffer()->getStride() * j * 4);
267 for (uint32_t i = 0; i < width; i++) {
268 dst[0] = color.r;
269 dst[1] = color.g;
270 dst[2] = color.b;
271 dst[3] = color.a;
272 dst += 4;
273 }
274 }
Alec Mouricdf6cbc2021-11-01 17:21:15 -0700275 buffer->getBuffer()->unlock();
276 return buffer;
277 }
278
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -0500279 std::shared_ptr<renderengine::ExternalTexture> allocateR8Buffer(int width, int height) {
280 auto buffer = new GraphicBuffer(width, height, android::PIXEL_FORMAT_R_8, 1,
281 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
282 GRALLOC_USAGE_HW_TEXTURE,
283 "r8");
284 if (buffer->initCheck() != 0) {
285 // Devices are not required to support R8.
286 return nullptr;
287 }
288 return std::make_shared<
289 renderengine::impl::ExternalTexture>(std::move(buffer), *mRE,
290 renderengine::impl::ExternalTexture::Usage::
291 READABLE);
292 }
293
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800294 RenderEngineTest() {
295 const ::testing::TestInfo* const test_info =
296 ::testing::UnitTest::GetInstance()->current_test_info();
297 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800298 }
Alec Mouri1089aed2018-10-25 21:33:57 -0700299
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800300 ~RenderEngineTest() {
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800301 if (WRITE_BUFFER_TO_FILE_ON_FAILURE && ::testing::Test::HasFailure()) {
302 writeBufferToFile("/data/texture_out_");
303 }
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800304 for (uint32_t texName : mTexNames) {
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800305 mRE->deleteTextures(1, &texName);
Alec Mouric0aae732021-01-12 13:32:18 -0800306 if (mGLESRE != nullptr) {
307 EXPECT_FALSE(mGLESRE->isTextureNameKnownForTesting(texName));
308 }
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800309 }
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800310 const ::testing::TestInfo* const test_info =
311 ::testing::UnitTest::GetInstance()->current_test_info();
312 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800313 }
314
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800315 void writeBufferToFile(const char* basename) {
316 std::string filename(basename);
317 filename.append(::testing::UnitTest::GetInstance()->current_test_info()->name());
318 filename.append(".ppm");
319 std::ofstream file(filename.c_str(), std::ios::binary);
320 if (!file.is_open()) {
321 ALOGE("Unable to open file: %s", filename.c_str());
322 ALOGE("You may need to do: \"adb shell setenforce 0\" to enable "
323 "surfaceflinger to write debug images");
324 return;
325 }
326
Alec Mouri1089aed2018-10-25 21:33:57 -0700327 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +0000328 mBuffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
329 reinterpret_cast<void**>(&pixels));
Alec Mouri1089aed2018-10-25 21:33:57 -0700330
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800331 file << "P6\n";
Alec Mouria90a5702021-04-16 16:36:21 +0000332 file << mBuffer->getBuffer()->getWidth() << "\n";
333 file << mBuffer->getBuffer()->getHeight() << "\n";
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800334 file << 255 << "\n";
335
Alec Mouria90a5702021-04-16 16:36:21 +0000336 std::vector<uint8_t> outBuffer(mBuffer->getBuffer()->getWidth() *
337 mBuffer->getBuffer()->getHeight() * 3);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800338 auto outPtr = reinterpret_cast<uint8_t*>(outBuffer.data());
339
Alec Mouria90a5702021-04-16 16:36:21 +0000340 for (int32_t j = 0; j < mBuffer->getBuffer()->getHeight(); j++) {
341 const uint8_t* src = pixels + (mBuffer->getBuffer()->getStride() * j) * 4;
342 for (int32_t i = 0; i < mBuffer->getBuffer()->getWidth(); i++) {
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800343 // Only copy R, G and B components
344 outPtr[0] = src[0];
345 outPtr[1] = src[1];
346 outPtr[2] = src[2];
347 outPtr += 3;
348
349 src += 4;
350 }
351 }
352 file.write(reinterpret_cast<char*>(outBuffer.data()), outBuffer.size());
Alec Mouria90a5702021-04-16 16:36:21 +0000353 mBuffer->getBuffer()->unlock();
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800354 }
355
356 void expectBufferColor(const Region& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
357 size_t c;
358 Rect const* rect = region.getArray(&c);
359 for (size_t i = 0; i < c; i++, rect++) {
360 expectBufferColor(*rect, r, g, b, a);
361 }
362 }
363
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -0400364 void expectBufferColor(const Point& point, uint8_t r, uint8_t g, uint8_t b, uint8_t a,
365 uint8_t tolerance = 0) {
366 expectBufferColor(Rect(point.x, point.y, point.x + 1, point.y + 1), r, g, b, a, tolerance);
367 }
368
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800369 void expectBufferColor(const Rect& rect, uint8_t r, uint8_t g, uint8_t b, uint8_t a,
370 uint8_t tolerance = 0) {
Alec Mouri4049b532021-10-15 20:59:33 -0700371 auto generator = [=](Point) { return ubyte4(r, g, b, a); };
372 expectBufferColor(rect, generator, tolerance);
373 }
374
375 using ColorGenerator = std::function<ubyte4(Point location)>;
376
377 void expectBufferColor(const Rect& rect, ColorGenerator generator, uint8_t tolerance = 0) {
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800378 auto colorCompare = [tolerance](const uint8_t* colorA, const uint8_t* colorB) {
379 auto colorBitCompare = [tolerance](uint8_t a, uint8_t b) {
380 uint8_t tmp = a >= b ? a - b : b - a;
381 return tmp <= tolerance;
382 };
383 return std::equal(colorA, colorA + 4, colorB, colorBitCompare);
Alec Mouri1089aed2018-10-25 21:33:57 -0700384 };
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800385
Alec Mouri4049b532021-10-15 20:59:33 -0700386 expectBufferColor(rect, generator, colorCompare);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800387 }
388
Alec Mouri4049b532021-10-15 20:59:33 -0700389 void expectBufferColor(const Rect& region, ColorGenerator generator,
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800390 std::function<bool(const uint8_t* a, const uint8_t* b)> colorCompare) {
391 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +0000392 mBuffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
393 reinterpret_cast<void**>(&pixels));
Alec Mouri1089aed2018-10-25 21:33:57 -0700394 int32_t maxFails = 10;
395 int32_t fails = 0;
396 for (int32_t j = 0; j < region.getHeight(); j++) {
Alec Mouria90a5702021-04-16 16:36:21 +0000397 const uint8_t* src = pixels +
398 (mBuffer->getBuffer()->getStride() * (region.top + j) + region.left) * 4;
Alec Mouri1089aed2018-10-25 21:33:57 -0700399 for (int32_t i = 0; i < region.getWidth(); i++) {
Alec Mouri4049b532021-10-15 20:59:33 -0700400 const auto location = Point(region.left + i, region.top + j);
401 const ubyte4 colors = generator(location);
402 const uint8_t expected[4] = {colors.r, colors.g, colors.b, colors.a};
403 bool colorMatches = colorCompare(src, expected);
404 EXPECT_TRUE(colorMatches)
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -0400405 << GetParam()->name().c_str() << ": "
Alec Mouri4049b532021-10-15 20:59:33 -0700406 << "pixel @ (" << location.x << ", " << location.y << "): "
407 << "expected (" << static_cast<uint32_t>(colors.r) << ", "
408 << static_cast<uint32_t>(colors.g) << ", "
409 << static_cast<uint32_t>(colors.b) << ", "
410 << static_cast<uint32_t>(colors.a) << "), "
Alec Mouri1089aed2018-10-25 21:33:57 -0700411 << "got (" << static_cast<uint32_t>(src[0]) << ", "
412 << static_cast<uint32_t>(src[1]) << ", " << static_cast<uint32_t>(src[2])
413 << ", " << static_cast<uint32_t>(src[3]) << ")";
414 src += 4;
Alec Mouri4049b532021-10-15 20:59:33 -0700415 if (!colorMatches && ++fails >= maxFails) {
Alec Mouri1089aed2018-10-25 21:33:57 -0700416 break;
417 }
418 }
419 if (fails >= maxFails) {
420 break;
421 }
422 }
Alec Mouria90a5702021-04-16 16:36:21 +0000423 mBuffer->getBuffer()->unlock();
Alec Mouri1089aed2018-10-25 21:33:57 -0700424 }
425
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800426 void expectAlpha(const Rect& rect, uint8_t a) {
Alec Mouri4049b532021-10-15 20:59:33 -0700427 auto generator = [=](Point) { return ubyte4(0, 0, 0, a); };
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800428 auto colorCompare = [](const uint8_t* colorA, const uint8_t* colorB) {
429 return colorA[3] == colorB[3];
430 };
Alec Mouri4049b532021-10-15 20:59:33 -0700431 expectBufferColor(rect, generator, colorCompare);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800432 }
433
434 void expectShadowColor(const renderengine::LayerSettings& castingLayer,
435 const renderengine::ShadowSettings& shadow, const ubyte4& casterColor,
436 const ubyte4& backgroundColor) {
437 const Rect casterRect(castingLayer.geometry.boundaries);
438 Region casterRegion = Region(casterRect);
439 const float casterCornerRadius = castingLayer.geometry.roundedCornersRadius;
440 if (casterCornerRadius > 0.0f) {
441 // ignore the corners if a corner radius is set
442 Rect cornerRect(casterCornerRadius, casterCornerRadius);
443 casterRegion.subtractSelf(cornerRect.offsetTo(casterRect.left, casterRect.top));
444 casterRegion.subtractSelf(
445 cornerRect.offsetTo(casterRect.right - casterCornerRadius, casterRect.top));
446 casterRegion.subtractSelf(
447 cornerRect.offsetTo(casterRect.left, casterRect.bottom - casterCornerRadius));
448 casterRegion.subtractSelf(cornerRect.offsetTo(casterRect.right - casterCornerRadius,
449 casterRect.bottom - casterCornerRadius));
450 }
451
452 const float shadowInset = shadow.length * -1.0f;
453 const Rect casterWithShadow =
454 Rect(casterRect).inset(shadowInset, shadowInset, shadowInset, shadowInset);
455 const Region shadowRegion = Region(casterWithShadow).subtractSelf(casterRect);
456 const Region backgroundRegion = Region(fullscreenRect()).subtractSelf(casterWithShadow);
457
458 // verify casting layer
459 expectBufferColor(casterRegion, casterColor.r, casterColor.g, casterColor.b, casterColor.a);
460
461 // verify shadows by testing just the alpha since its difficult to validate the shadow color
462 size_t c;
463 Rect const* r = shadowRegion.getArray(&c);
464 for (size_t i = 0; i < c; i++, r++) {
465 expectAlpha(*r, 255);
466 }
467
468 // verify background
469 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
470 backgroundColor.a);
471 }
472
Alec Mouribd17b3b2020-12-17 11:08:30 -0800473 void expectShadowColorWithoutCaster(const FloatRect& casterBounds,
474 const renderengine::ShadowSettings& shadow,
475 const ubyte4& backgroundColor) {
476 const float shadowInset = shadow.length * -1.0f;
477 const Rect casterRect(casterBounds);
478 const Rect shadowRect =
479 Rect(casterRect).inset(shadowInset, shadowInset, shadowInset, shadowInset);
480
481 const Region backgroundRegion =
482 Region(fullscreenRect()).subtractSelf(casterRect).subtractSelf(shadowRect);
483
484 expectAlpha(shadowRect, 255);
485 // (0, 0, 0) fill on the bounds of the layer should be ignored.
486 expectBufferColor(casterRect, 255, 255, 255, 255, 254);
487
488 // verify background
489 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
490 backgroundColor.a);
491 }
492
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800493 static renderengine::ShadowSettings getShadowSettings(const vec2& casterPos, float shadowLength,
494 bool casterIsTranslucent) {
495 renderengine::ShadowSettings shadow;
496 shadow.ambientColor = {0.0f, 0.0f, 0.0f, 0.039f};
497 shadow.spotColor = {0.0f, 0.0f, 0.0f, 0.19f};
498 shadow.lightPos = vec3(casterPos.x, casterPos.y, 0);
499 shadow.lightRadius = 0.0f;
500 shadow.length = shadowLength;
501 shadow.casterIsTranslucent = casterIsTranslucent;
502 return shadow;
503 }
504
Alec Mouri1089aed2018-10-25 21:33:57 -0700505 static Rect fullscreenRect() { return Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT); }
506
507 static Rect offsetRect() {
508 return Rect(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_WIDTH,
509 DEFAULT_DISPLAY_HEIGHT);
510 }
511
512 static Rect offsetRectAtZero() {
513 return Rect(DEFAULT_DISPLAY_WIDTH - DEFAULT_DISPLAY_OFFSET,
514 DEFAULT_DISPLAY_HEIGHT - DEFAULT_DISPLAY_OFFSET);
515 }
516
Sally Qi59a9f502021-10-12 18:53:23 +0000517 void invokeDraw(const renderengine::DisplaySettings& settings,
518 const std::vector<renderengine::LayerSettings>& layers) {
Sally Qi4cabdd02021-08-05 16:45:57 -0700519 std::future<renderengine::RenderEngineResult> result =
520 mRE->drawLayers(settings, layers, mBuffer, true, base::unique_fd());
Sally Qi59a9f502021-10-12 18:53:23 +0000521
Sally Qi4cabdd02021-08-05 16:45:57 -0700522 ASSERT_TRUE(result.valid());
523 auto [status, fence] = result.get();
Alec Mouri1089aed2018-10-25 21:33:57 -0700524
Derek Sollenbergerec411212021-08-25 10:54:47 -0400525 ASSERT_EQ(NO_ERROR, status);
526 if (fence.ok()) {
527 sync_wait(fence.get(), -1);
Alec Mouri1089aed2018-10-25 21:33:57 -0700528 }
529
Alec Mouric0aae732021-01-12 13:32:18 -0800530 if (layers.size() > 0 && mGLESRE != nullptr) {
Alec Mouria90a5702021-04-16 16:36:21 +0000531 ASSERT_TRUE(mGLESRE->isFramebufferImageCachedForTesting(mBuffer->getBuffer()->getId()));
Alec Mourid43ccab2019-03-13 12:23:45 -0700532 }
Alec Mouri1089aed2018-10-25 21:33:57 -0700533 }
534
Alec Mourid43ccab2019-03-13 12:23:45 -0700535 void drawEmptyLayers() {
Alec Mouri6e57f682018-09-29 20:45:08 -0700536 renderengine::DisplaySettings settings;
Sally Qi59a9f502021-10-12 18:53:23 +0000537 std::vector<renderengine::LayerSettings> layers;
Alec Mouric0aae732021-01-12 13:32:18 -0800538 invokeDraw(settings, layers);
Alec Mouri6e57f682018-09-29 20:45:08 -0700539 }
540
Alec Mouri1089aed2018-10-25 21:33:57 -0700541 template <typename SourceVariant>
542 void fillBuffer(half r, half g, half b, half a);
543
544 template <typename SourceVariant>
545 void fillRedBuffer();
546
547 template <typename SourceVariant>
548 void fillGreenBuffer();
549
550 template <typename SourceVariant>
551 void fillBlueBuffer();
552
553 template <typename SourceVariant>
554 void fillRedTransparentBuffer();
555
556 template <typename SourceVariant>
557 void fillRedOffsetBuffer();
558
559 template <typename SourceVariant>
560 void fillBufferPhysicalOffset();
561
562 template <typename SourceVariant>
Alec Mouri5a6d8572020-03-23 23:56:15 -0700563 void fillBufferCheckers(uint32_t rotation);
Alec Mouri1089aed2018-10-25 21:33:57 -0700564
565 template <typename SourceVariant>
566 void fillBufferCheckersRotate0();
567
568 template <typename SourceVariant>
569 void fillBufferCheckersRotate90();
570
571 template <typename SourceVariant>
572 void fillBufferCheckersRotate180();
573
574 template <typename SourceVariant>
575 void fillBufferCheckersRotate270();
576
577 template <typename SourceVariant>
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800578 void fillBufferWithLayerTransform();
579
580 template <typename SourceVariant>
Alec Mouri1089aed2018-10-25 21:33:57 -0700581 void fillBufferLayerTransform();
582
583 template <typename SourceVariant>
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800584 void fillBufferWithColorTransform();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800585
586 template <typename SourceVariant>
Alec Mouri1089aed2018-10-25 21:33:57 -0700587 void fillBufferColorTransform();
588
Alec Mouri7c94edb2018-12-03 21:23:26 -0800589 template <typename SourceVariant>
Sally Qi2019fd22021-11-22 10:19:04 -0800590 void fillBufferWithColorTransformAndSourceDataspace(const ui::Dataspace sourceDataspace);
591
592 template <typename SourceVariant>
593 void fillBufferColorTransformAndSourceDataspace();
594
595 template <typename SourceVariant>
596 void fillBufferWithColorTransformAndOutputDataspace(const ui::Dataspace outputDataspace);
597
598 template <typename SourceVariant>
599 void fillBufferColorTransformAndOutputDataspace();
600
601 template <typename SourceVariant>
KaiChieh Chuangda2845c2020-12-14 16:49:38 +0800602 void fillBufferWithColorTransformZeroLayerAlpha();
603
604 template <typename SourceVariant>
605 void fillBufferColorTransformZeroLayerAlpha();
606
607 template <typename SourceVariant>
Alec Mouri7c94edb2018-12-03 21:23:26 -0800608 void fillRedBufferWithRoundedCorners();
609
610 template <typename SourceVariant>
611 void fillBufferWithRoundedCorners();
612
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000613 template <typename SourceVariant>
Lucas Dupin19c8f0e2019-11-25 17:55:44 -0800614 void fillBufferAndBlurBackground();
615
616 template <typename SourceVariant>
Alec Mourie8489fd2021-04-29 16:08:56 -0700617 void fillSmallLayerAndBlurBackground();
618
619 template <typename SourceVariant>
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000620 void overlayCorners();
621
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800622 void fillRedBufferTextureTransform();
623
624 void fillBufferTextureTransform();
625
626 void fillRedBufferWithPremultiplyAlpha();
627
628 void fillBufferWithPremultiplyAlpha();
629
630 void fillRedBufferWithoutPremultiplyAlpha();
631
632 void fillBufferWithoutPremultiplyAlpha();
633
Alec Mouriac335532018-11-12 15:01:33 -0800634 void fillGreenColorBufferThenClearRegion();
635
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800636 template <typename SourceVariant>
637 void drawShadow(const renderengine::LayerSettings& castingLayer,
638 const renderengine::ShadowSettings& shadow, const ubyte4& casterColor,
639 const ubyte4& backgroundColor);
640
Alec Mouribd17b3b2020-12-17 11:08:30 -0800641 void drawShadowWithoutCaster(const FloatRect& castingBounds,
642 const renderengine::ShadowSettings& shadow,
643 const ubyte4& backgroundColor);
644
Alec Mouri5a493722022-01-26 16:43:02 -0800645 // Tonemaps grey values from sourceDataspace -> Display P3 and checks that GPU and CPU
646 // implementations are identical Also implicitly checks that the injected tonemap shader
647 // compiles
648 void tonemap(ui::Dataspace sourceDataspace, std::function<vec3(vec3)> eotf,
649 std::function<vec3(vec3, float)> scaleOotf);
650
Alec Mouric0aae732021-01-12 13:32:18 -0800651 void initializeRenderEngine();
652
653 std::unique_ptr<renderengine::RenderEngine> mRE;
Alec Mouria90a5702021-04-16 16:36:21 +0000654 std::shared_ptr<renderengine::ExternalTexture> mBuffer;
Alec Mouric0aae732021-01-12 13:32:18 -0800655 // GLESRenderEngine for testing GLES-specific behavior.
656 // Owened by mRE, but this is downcasted.
657 renderengine::gl::GLESRenderEngine* mGLESRE = nullptr;
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800658
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800659 std::vector<uint32_t> mTexNames;
Alec Mouri6e57f682018-09-29 20:45:08 -0700660};
661
Alec Mouric0aae732021-01-12 13:32:18 -0800662void RenderEngineTest::initializeRenderEngine() {
663 const auto& renderEngineFactory = GetParam();
664 if (renderEngineFactory->type() == renderengine::RenderEngine::RenderEngineType::GLES) {
665 // Only GLESRenderEngine exposes test-only methods. Provide a pointer to the
666 // GLESRenderEngine if we're using it so that we don't need to dynamic_cast
667 // every time.
668 std::unique_ptr<renderengine::gl::GLESRenderEngine> renderEngine =
669 renderEngineFactory->createGLESRenderEngine();
670 mGLESRE = renderEngine.get();
671 mRE = std::move(renderEngine);
672 } else {
673 mRE = renderEngineFactory->createRenderEngine();
674 }
Alec Mouria90a5702021-04-16 16:36:21 +0000675 mBuffer = allocateDefaultBuffer();
Alec Mouric0aae732021-01-12 13:32:18 -0800676}
677
Alec Mouri1089aed2018-10-25 21:33:57 -0700678struct ColorSourceVariant {
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800679 static void fillColor(renderengine::LayerSettings& layer, half r, half g, half b,
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800680 RenderEngineTest* /*fixture*/) {
Alec Mouri1089aed2018-10-25 21:33:57 -0700681 layer.source.solidColor = half3(r, g, b);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800682 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700683 }
684};
685
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800686struct RelaxOpaqueBufferVariant {
687 static void setOpaqueBit(renderengine::LayerSettings& layer) {
688 layer.source.buffer.isOpaque = false;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800689 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800690 }
691
692 static uint8_t getAlphaChannel() { return 255; }
693};
694
695struct ForceOpaqueBufferVariant {
696 static void setOpaqueBit(renderengine::LayerSettings& layer) {
697 layer.source.buffer.isOpaque = true;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800698 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800699 }
700
701 static uint8_t getAlphaChannel() {
702 // The isOpaque bit will override the alpha channel, so this should be
703 // arbitrary.
Alec Mouric0aae732021-01-12 13:32:18 -0800704 return 50;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800705 }
706};
707
708template <typename OpaquenessVariant>
709struct BufferSourceVariant {
710 static void fillColor(renderengine::LayerSettings& layer, half r, half g, half b,
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800711 RenderEngineTest* fixture) {
Alec Mouria90a5702021-04-16 16:36:21 +0000712 const auto buf = fixture->allocateSourceBuffer(1, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800713 uint32_t texName;
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800714 fixture->mRE->genTextures(1, &texName);
715 fixture->mTexNames.push_back(texName);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800716
717 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +0000718 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
719 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800720
Alec Mouria90a5702021-04-16 16:36:21 +0000721 for (int32_t j = 0; j < buf->getBuffer()->getHeight(); j++) {
722 uint8_t* iter = pixels + (buf->getBuffer()->getStride() * j) * 4;
723 for (int32_t i = 0; i < buf->getBuffer()->getWidth(); i++) {
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800724 iter[0] = uint8_t(r * 255);
725 iter[1] = uint8_t(g * 255);
726 iter[2] = uint8_t(b * 255);
727 iter[3] = OpaquenessVariant::getAlphaChannel();
728 iter += 4;
729 }
730 }
731
Alec Mouria90a5702021-04-16 16:36:21 +0000732 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800733
734 layer.source.buffer.buffer = buf;
735 layer.source.buffer.textureName = texName;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800736 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800737 OpaquenessVariant::setOpaqueBit(layer);
738 }
739};
740
Alec Mouri1089aed2018-10-25 21:33:57 -0700741template <typename SourceVariant>
742void RenderEngineTest::fillBuffer(half r, half g, half b, half a) {
743 renderengine::DisplaySettings settings;
744 settings.physicalDisplay = fullscreenRect();
745 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800746 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700747
Sally Qi59a9f502021-10-12 18:53:23 +0000748 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700749
750 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800751 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700752 layer.geometry.boundaries = fullscreenRect().toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800753 SourceVariant::fillColor(layer, r, g, b, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700754 layer.alpha = a;
755
Sally Qi59a9f502021-10-12 18:53:23 +0000756 layers.push_back(layer);
Alec Mouri1089aed2018-10-25 21:33:57 -0700757
Alec Mouric0aae732021-01-12 13:32:18 -0800758 invokeDraw(settings, layers);
Alec Mouri1089aed2018-10-25 21:33:57 -0700759}
760
761template <typename SourceVariant>
762void RenderEngineTest::fillRedBuffer() {
763 fillBuffer<SourceVariant>(1.0f, 0.0f, 0.0f, 1.0f);
764 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
765}
766
767template <typename SourceVariant>
768void RenderEngineTest::fillGreenBuffer() {
769 fillBuffer<SourceVariant>(0.0f, 1.0f, 0.0f, 1.0f);
770 expectBufferColor(fullscreenRect(), 0, 255, 0, 255);
771}
772
773template <typename SourceVariant>
774void RenderEngineTest::fillBlueBuffer() {
775 fillBuffer<SourceVariant>(0.0f, 0.0f, 1.0f, 1.0f);
776 expectBufferColor(fullscreenRect(), 0, 0, 255, 255);
777}
778
779template <typename SourceVariant>
780void RenderEngineTest::fillRedTransparentBuffer() {
781 fillBuffer<SourceVariant>(1.0f, 0.0f, 0.0f, .2f);
782 expectBufferColor(fullscreenRect(), 51, 0, 0, 51);
783}
784
785template <typename SourceVariant>
786void RenderEngineTest::fillRedOffsetBuffer() {
787 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800788 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700789 settings.physicalDisplay = offsetRect();
790 settings.clip = offsetRectAtZero();
791
Sally Qi59a9f502021-10-12 18:53:23 +0000792 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700793
794 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800795 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700796 layer.geometry.boundaries = offsetRectAtZero().toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800797 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700798 layer.alpha = 1.0f;
799
Sally Qi59a9f502021-10-12 18:53:23 +0000800 layers.push_back(layer);
Alec Mouric0aae732021-01-12 13:32:18 -0800801 invokeDraw(settings, layers);
Alec Mouri1089aed2018-10-25 21:33:57 -0700802}
803
804template <typename SourceVariant>
805void RenderEngineTest::fillBufferPhysicalOffset() {
806 fillRedOffsetBuffer<SourceVariant>();
807
808 expectBufferColor(Rect(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_WIDTH,
809 DEFAULT_DISPLAY_HEIGHT),
810 255, 0, 0, 255);
811 Rect offsetRegionLeft(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_HEIGHT);
812 Rect offsetRegionTop(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_OFFSET);
813
814 expectBufferColor(offsetRegionLeft, 0, 0, 0, 0);
815 expectBufferColor(offsetRegionTop, 0, 0, 0, 0);
816}
817
818template <typename SourceVariant>
Alec Mouri5a6d8572020-03-23 23:56:15 -0700819void RenderEngineTest::fillBufferCheckers(uint32_t orientationFlag) {
Alec Mouri1089aed2018-10-25 21:33:57 -0700820 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800821 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700822 settings.physicalDisplay = fullscreenRect();
823 // Here logical space is 2x2
824 settings.clip = Rect(2, 2);
Alec Mouri5a6d8572020-03-23 23:56:15 -0700825 settings.orientation = orientationFlag;
Alec Mouri1089aed2018-10-25 21:33:57 -0700826
Sally Qi59a9f502021-10-12 18:53:23 +0000827 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700828
829 renderengine::LayerSettings layerOne;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800830 layerOne.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700831 Rect rectOne(0, 0, 1, 1);
832 layerOne.geometry.boundaries = rectOne.toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800833 SourceVariant::fillColor(layerOne, 1.0f, 0.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700834 layerOne.alpha = 1.0f;
835
836 renderengine::LayerSettings layerTwo;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800837 layerTwo.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700838 Rect rectTwo(0, 1, 1, 2);
839 layerTwo.geometry.boundaries = rectTwo.toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800840 SourceVariant::fillColor(layerTwo, 0.0f, 1.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700841 layerTwo.alpha = 1.0f;
842
843 renderengine::LayerSettings layerThree;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800844 layerThree.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700845 Rect rectThree(1, 0, 2, 1);
846 layerThree.geometry.boundaries = rectThree.toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800847 SourceVariant::fillColor(layerThree, 0.0f, 0.0f, 1.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700848 layerThree.alpha = 1.0f;
849
Sally Qi59a9f502021-10-12 18:53:23 +0000850 layers.push_back(layerOne);
851 layers.push_back(layerTwo);
852 layers.push_back(layerThree);
Alec Mouri1089aed2018-10-25 21:33:57 -0700853
Alec Mouric0aae732021-01-12 13:32:18 -0800854 invokeDraw(settings, layers);
Alec Mouri1089aed2018-10-25 21:33:57 -0700855}
856
857template <typename SourceVariant>
858void RenderEngineTest::fillBufferCheckersRotate0() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700859 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_0);
Alec Mouri1089aed2018-10-25 21:33:57 -0700860 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0,
861 255);
862 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
863 DEFAULT_DISPLAY_HEIGHT / 2),
864 0, 0, 255, 255);
865 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
866 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
867 0, 0, 0, 0);
868 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
869 DEFAULT_DISPLAY_HEIGHT),
870 0, 255, 0, 255);
871}
872
873template <typename SourceVariant>
874void RenderEngineTest::fillBufferCheckersRotate90() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700875 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_90);
Alec Mouri1089aed2018-10-25 21:33:57 -0700876 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 255, 0,
877 255);
878 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
879 DEFAULT_DISPLAY_HEIGHT / 2),
880 255, 0, 0, 255);
881 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
882 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
883 0, 0, 255, 255);
884 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
885 DEFAULT_DISPLAY_HEIGHT),
886 0, 0, 0, 0);
887}
888
889template <typename SourceVariant>
890void RenderEngineTest::fillBufferCheckersRotate180() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700891 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_180);
Alec Mouri1089aed2018-10-25 21:33:57 -0700892 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 0,
893 0);
894 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
895 DEFAULT_DISPLAY_HEIGHT / 2),
896 0, 255, 0, 255);
897 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
898 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
899 255, 0, 0, 255);
900 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
901 DEFAULT_DISPLAY_HEIGHT),
902 0, 0, 255, 255);
903}
904
905template <typename SourceVariant>
906void RenderEngineTest::fillBufferCheckersRotate270() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700907 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_270);
Alec Mouri1089aed2018-10-25 21:33:57 -0700908 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 255,
909 255);
910 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
911 DEFAULT_DISPLAY_HEIGHT / 2),
912 0, 0, 0, 0);
913 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
914 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
915 0, 255, 0, 255);
916 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
917 DEFAULT_DISPLAY_HEIGHT),
918 255, 0, 0, 255);
919}
920
921template <typename SourceVariant>
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800922void RenderEngineTest::fillBufferWithLayerTransform() {
Alec Mouri1089aed2018-10-25 21:33:57 -0700923 renderengine::DisplaySettings settings;
924 settings.physicalDisplay = fullscreenRect();
925 // Here logical space is 2x2
926 settings.clip = Rect(2, 2);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800927 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700928
Sally Qi59a9f502021-10-12 18:53:23 +0000929 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700930
931 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800932 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700933 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
934 // Translate one pixel diagonally
935 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 -0800936 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700937 layer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
938 layer.alpha = 1.0f;
939
Sally Qi59a9f502021-10-12 18:53:23 +0000940 layers.push_back(layer);
Alec Mouri1089aed2018-10-25 21:33:57 -0700941
Alec Mouric0aae732021-01-12 13:32:18 -0800942 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800943}
Alec Mouri1089aed2018-10-25 21:33:57 -0700944
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800945template <typename SourceVariant>
946void RenderEngineTest::fillBufferLayerTransform() {
947 fillBufferWithLayerTransform<SourceVariant>();
Alec Mouri1089aed2018-10-25 21:33:57 -0700948 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 0, 0);
949 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
950 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
951 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
952 255, 0, 0, 255);
953}
954
955template <typename SourceVariant>
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800956void RenderEngineTest::fillBufferWithColorTransform() {
Alec Mouri1089aed2018-10-25 21:33:57 -0700957 renderengine::DisplaySettings settings;
958 settings.physicalDisplay = fullscreenRect();
959 settings.clip = Rect(1, 1);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800960 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700961
Sally Qi59a9f502021-10-12 18:53:23 +0000962 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700963
964 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800965 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700966 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800967 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700968 layer.alpha = 1.0f;
969
970 // construct a fake color matrix
971 // annihilate green and blue channels
KaiChieh Chuang436fc192020-09-07 13:48:42 +0800972 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
Alec Mouri1089aed2018-10-25 21:33:57 -0700973 // set red channel to red + green
974 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
975
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800976 layer.alpha = 1.0f;
977 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
978
Sally Qi59a9f502021-10-12 18:53:23 +0000979 layers.push_back(layer);
Alec Mouri1089aed2018-10-25 21:33:57 -0700980
Alec Mouric0aae732021-01-12 13:32:18 -0800981 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800982}
Alec Mouri1089aed2018-10-25 21:33:57 -0700983
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800984template <typename SourceVariant>
Sally Qi2019fd22021-11-22 10:19:04 -0800985void RenderEngineTest::fillBufferWithColorTransformAndSourceDataspace(
986 const ui::Dataspace sourceDataspace) {
987 renderengine::DisplaySettings settings;
988 settings.physicalDisplay = fullscreenRect();
989 settings.clip = Rect(1, 1);
990 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
991
992 std::vector<renderengine::LayerSettings> layers;
993
994 renderengine::LayerSettings layer;
995 layer.sourceDataspace = sourceDataspace;
996 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
997 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
998 layer.alpha = 1.0f;
999
1000 // construct a fake color matrix
1001 // annihilate green and blue channels
1002 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
1003 // set red channel to red + green
1004 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
1005
1006 layer.alpha = 1.0f;
1007 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1008
1009 layers.push_back(layer);
1010
1011 invokeDraw(settings, layers);
1012}
1013
1014template <typename SourceVariant>
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001015void RenderEngineTest::fillBufferColorTransform() {
1016 fillBufferWithColorTransform<SourceVariant>();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08001017 expectBufferColor(fullscreenRect(), 172, 0, 0, 255, 1);
1018}
1019
1020template <typename SourceVariant>
Sally Qi2019fd22021-11-22 10:19:04 -08001021void RenderEngineTest::fillBufferColorTransformAndSourceDataspace() {
1022 unordered_map<ui::Dataspace, ubyte4> dataspaceToColorMap;
1023 dataspaceToColorMap[ui::Dataspace::V0_BT709] = {172, 0, 0, 255};
1024 dataspaceToColorMap[ui::Dataspace::BT2020] = {172, 0, 0, 255};
1025 dataspaceToColorMap[ui::Dataspace::ADOBE_RGB] = {172, 0, 0, 255};
1026 ui::Dataspace customizedDataspace = static_cast<ui::Dataspace>(
1027 ui::Dataspace::STANDARD_BT709 | ui::Dataspace::TRANSFER_GAMMA2_2 |
1028 ui::Dataspace::RANGE_FULL);
1029 dataspaceToColorMap[customizedDataspace] = {172, 0, 0, 255};
1030 for (const auto& [sourceDataspace, color] : dataspaceToColorMap) {
1031 fillBufferWithColorTransformAndSourceDataspace<SourceVariant>(sourceDataspace);
1032 expectBufferColor(fullscreenRect(), color.r, color.g, color.b, color.a, 1);
1033 }
1034}
1035
1036template <typename SourceVariant>
1037void RenderEngineTest::fillBufferWithColorTransformAndOutputDataspace(
1038 const ui::Dataspace outputDataspace) {
1039 renderengine::DisplaySettings settings;
1040 settings.physicalDisplay = fullscreenRect();
1041 settings.clip = Rect(1, 1);
1042 settings.outputDataspace = outputDataspace;
1043
1044 std::vector<renderengine::LayerSettings> layers;
1045
1046 renderengine::LayerSettings layer;
1047 layer.sourceDataspace = ui::Dataspace::V0_SCRGB_LINEAR;
1048 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1049 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
1050 layer.alpha = 1.0f;
1051
1052 // construct a fake color matrix
1053 // annihilate green and blue channels
1054 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
1055 // set red channel to red + green
1056 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
1057
1058 layer.alpha = 1.0f;
1059 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1060
1061 layers.push_back(layer);
1062
1063 invokeDraw(settings, layers);
1064}
1065
1066template <typename SourceVariant>
1067void RenderEngineTest::fillBufferColorTransformAndOutputDataspace() {
1068 unordered_map<ui::Dataspace, ubyte4> dataspaceToColorMap;
1069 dataspaceToColorMap[ui::Dataspace::V0_BT709] = {202, 0, 0, 255};
1070 dataspaceToColorMap[ui::Dataspace::BT2020] = {192, 0, 0, 255};
1071 dataspaceToColorMap[ui::Dataspace::ADOBE_RGB] = {202, 0, 0, 255};
1072 ui::Dataspace customizedDataspace = static_cast<ui::Dataspace>(
1073 ui::Dataspace::STANDARD_BT709 | ui::Dataspace::TRANSFER_GAMMA2_6 |
1074 ui::Dataspace::RANGE_FULL);
1075 dataspaceToColorMap[customizedDataspace] = {202, 0, 0, 255};
1076 for (const auto& [outputDataspace, color] : dataspaceToColorMap) {
1077 fillBufferWithColorTransformAndOutputDataspace<SourceVariant>(outputDataspace);
1078 expectBufferColor(fullscreenRect(), color.r, color.g, color.b, color.a, 1);
1079 }
1080}
1081
1082template <typename SourceVariant>
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001083void RenderEngineTest::fillBufferWithColorTransformZeroLayerAlpha() {
1084 renderengine::DisplaySettings settings;
1085 settings.physicalDisplay = fullscreenRect();
1086 settings.clip = Rect(1, 1);
1087
Sally Qi59a9f502021-10-12 18:53:23 +00001088 std::vector<renderengine::LayerSettings> layers;
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001089
1090 renderengine::LayerSettings layer;
1091 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1092 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
1093 layer.alpha = 0;
1094
1095 // construct a fake color matrix
1096 // simple inverse color
1097 settings.colorTransform = mat4(-1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 1, 1, 1, 1);
1098
1099 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1100
Sally Qi59a9f502021-10-12 18:53:23 +00001101 layers.push_back(layer);
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001102
Alec Mouric0aae732021-01-12 13:32:18 -08001103 invokeDraw(settings, layers);
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001104}
1105
1106template <typename SourceVariant>
1107void RenderEngineTest::fillBufferColorTransformZeroLayerAlpha() {
1108 fillBufferWithColorTransformZeroLayerAlpha<SourceVariant>();
1109 expectBufferColor(fullscreenRect(), 0, 0, 0, 0);
1110}
1111
1112template <typename SourceVariant>
Alec Mouri7c94edb2018-12-03 21:23:26 -08001113void RenderEngineTest::fillRedBufferWithRoundedCorners() {
1114 renderengine::DisplaySettings settings;
1115 settings.physicalDisplay = fullscreenRect();
1116 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001117 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri7c94edb2018-12-03 21:23:26 -08001118
Sally Qi59a9f502021-10-12 18:53:23 +00001119 std::vector<renderengine::LayerSettings> layers;
Alec Mouri7c94edb2018-12-03 21:23:26 -08001120
1121 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001122 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri7c94edb2018-12-03 21:23:26 -08001123 layer.geometry.boundaries = fullscreenRect().toFloatRect();
1124 layer.geometry.roundedCornersRadius = 5.0f;
1125 layer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
1126 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
1127 layer.alpha = 1.0f;
1128
Sally Qi59a9f502021-10-12 18:53:23 +00001129 layers.push_back(layer);
Alec Mouri7c94edb2018-12-03 21:23:26 -08001130
Alec Mouric0aae732021-01-12 13:32:18 -08001131 invokeDraw(settings, layers);
Alec Mouri7c94edb2018-12-03 21:23:26 -08001132}
1133
1134template <typename SourceVariant>
1135void RenderEngineTest::fillBufferWithRoundedCorners() {
1136 fillRedBufferWithRoundedCorners<SourceVariant>();
1137 // Corners should be ignored...
1138 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 0);
1139 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, 0, DEFAULT_DISPLAY_WIDTH, 1), 0, 0, 0, 0);
1140 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT - 1, 1, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
1141 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1,
1142 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1143 0, 0, 0, 0);
1144 // ...And the non-rounded portion should be red.
1145 // Other pixels may be anti-aliased, so let's not check those.
1146 expectBufferColor(Rect(5, 5, DEFAULT_DISPLAY_WIDTH - 5, DEFAULT_DISPLAY_HEIGHT - 5), 255, 0, 0,
1147 255);
1148}
1149
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001150template <typename SourceVariant>
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001151void RenderEngineTest::fillBufferAndBlurBackground() {
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001152 auto blurRadius = 50;
1153 auto center = DEFAULT_DISPLAY_WIDTH / 2;
1154
1155 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001156 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001157 settings.physicalDisplay = fullscreenRect();
1158 settings.clip = fullscreenRect();
1159
Sally Qi59a9f502021-10-12 18:53:23 +00001160 std::vector<renderengine::LayerSettings> layers;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001161
1162 renderengine::LayerSettings backgroundLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001163 backgroundLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001164 backgroundLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1165 SourceVariant::fillColor(backgroundLayer, 0.0f, 1.0f, 0.0f, this);
1166 backgroundLayer.alpha = 1.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001167 layers.emplace_back(backgroundLayer);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001168
1169 renderengine::LayerSettings leftLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001170 leftLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001171 leftLayer.geometry.boundaries =
1172 Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT).toFloatRect();
1173 SourceVariant::fillColor(leftLayer, 1.0f, 0.0f, 0.0f, this);
1174 leftLayer.alpha = 1.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001175 layers.emplace_back(leftLayer);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001176
1177 renderengine::LayerSettings blurLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001178 blurLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001179 blurLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1180 blurLayer.backgroundBlurRadius = blurRadius;
Derek Sollenbergerecb21462021-01-29 16:53:49 -05001181 SourceVariant::fillColor(blurLayer, 0.0f, 0.0f, 1.0f, this);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001182 blurLayer.alpha = 0;
Sally Qi59a9f502021-10-12 18:53:23 +00001183 layers.emplace_back(blurLayer);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001184
Alec Mouric0aae732021-01-12 13:32:18 -08001185 invokeDraw(settings, layers);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001186
Derek Sollenbergerecb21462021-01-29 16:53:49 -05001187 // solid color
1188 expectBufferColor(Rect(0, 0, 1, 1), 255, 0, 0, 255, 0 /* tolerance */);
1189
Derek Sollenbergerb3998372021-02-16 15:16:56 -05001190 if (mRE->supportsBackgroundBlur()) {
1191 // blurred color (downsampling should result in the center color being close to 128)
1192 expectBufferColor(Rect(center - 1, center - 5, center + 1, center + 5), 128, 128, 0, 255,
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001193 50 /* tolerance */);
Derek Sollenbergerb3998372021-02-16 15:16:56 -05001194 }
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001195}
1196
1197template <typename SourceVariant>
Alec Mourie8489fd2021-04-29 16:08:56 -07001198void RenderEngineTest::fillSmallLayerAndBlurBackground() {
1199 auto blurRadius = 50;
1200 renderengine::DisplaySettings settings;
1201 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1202 settings.physicalDisplay = fullscreenRect();
1203 settings.clip = fullscreenRect();
1204
Sally Qi59a9f502021-10-12 18:53:23 +00001205 std::vector<renderengine::LayerSettings> layers;
Alec Mourie8489fd2021-04-29 16:08:56 -07001206
1207 renderengine::LayerSettings backgroundLayer;
1208 backgroundLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1209 backgroundLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1210 SourceVariant::fillColor(backgroundLayer, 1.0f, 0.0f, 0.0f, this);
1211 backgroundLayer.alpha = 1.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001212 layers.push_back(backgroundLayer);
Alec Mourie8489fd2021-04-29 16:08:56 -07001213
1214 renderengine::LayerSettings blurLayer;
1215 blurLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1216 blurLayer.geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f);
1217 blurLayer.backgroundBlurRadius = blurRadius;
1218 SourceVariant::fillColor(blurLayer, 0.0f, 0.0f, 1.0f, this);
1219 blurLayer.alpha = 0;
Sally Qi59a9f502021-10-12 18:53:23 +00001220 layers.push_back(blurLayer);
Alec Mourie8489fd2021-04-29 16:08:56 -07001221
1222 invokeDraw(settings, layers);
1223
1224 // Give a generous tolerance - the blur rectangle is very small and this test is
1225 // mainly concerned with ensuring that there's no device failure.
1226 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT), 255, 0, 0, 255,
1227 40 /* tolerance */);
1228}
1229
1230template <typename SourceVariant>
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001231void RenderEngineTest::overlayCorners() {
1232 renderengine::DisplaySettings settings;
1233 settings.physicalDisplay = fullscreenRect();
1234 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001235 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001236
Sally Qi59a9f502021-10-12 18:53:23 +00001237 std::vector<renderengine::LayerSettings> layersFirst;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001238
1239 renderengine::LayerSettings layerOne;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001240 layerOne.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001241 layerOne.geometry.boundaries =
1242 FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH / 3.0, DEFAULT_DISPLAY_HEIGHT / 3.0);
1243 SourceVariant::fillColor(layerOne, 1.0f, 0.0f, 0.0f, this);
1244 layerOne.alpha = 0.2;
1245
Sally Qi59a9f502021-10-12 18:53:23 +00001246 layersFirst.push_back(layerOne);
Alec Mouric0aae732021-01-12 13:32:18 -08001247 invokeDraw(settings, layersFirst);
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001248 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3), 51, 0, 0, 51);
1249 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3 + 1, DEFAULT_DISPLAY_HEIGHT / 3 + 1,
1250 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1251 0, 0, 0, 0);
1252
Sally Qi59a9f502021-10-12 18:53:23 +00001253 std::vector<renderengine::LayerSettings> layersSecond;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001254 renderengine::LayerSettings layerTwo;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001255 layerTwo.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001256 layerTwo.geometry.boundaries =
1257 FloatRect(DEFAULT_DISPLAY_WIDTH / 3.0, DEFAULT_DISPLAY_HEIGHT / 3.0,
1258 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT);
1259 SourceVariant::fillColor(layerTwo, 0.0f, 1.0f, 0.0f, this);
1260 layerTwo.alpha = 1.0f;
1261
Sally Qi59a9f502021-10-12 18:53:23 +00001262 layersSecond.push_back(layerTwo);
Alec Mouric0aae732021-01-12 13:32:18 -08001263 invokeDraw(settings, layersSecond);
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001264
1265 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3), 0, 0, 0, 0);
1266 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3 + 1, DEFAULT_DISPLAY_HEIGHT / 3 + 1,
1267 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1268 0, 255, 0, 255);
1269}
1270
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001271void RenderEngineTest::fillRedBufferTextureTransform() {
1272 renderengine::DisplaySettings settings;
1273 settings.physicalDisplay = fullscreenRect();
1274 settings.clip = Rect(1, 1);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001275 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001276
Sally Qi59a9f502021-10-12 18:53:23 +00001277 std::vector<renderengine::LayerSettings> layers;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001278
1279 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001280 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001281 // Here will allocate a checker board texture, but transform texture
1282 // coordinates so that only the upper left is applied.
Alec Mouria90a5702021-04-16 16:36:21 +00001283 const auto buf = allocateSourceBuffer(2, 2);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001284 uint32_t texName;
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001285 RenderEngineTest::mRE->genTextures(1, &texName);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001286 this->mTexNames.push_back(texName);
1287
1288 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00001289 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1290 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001291 // Red top left, Green top right, Blue bottom left, Black bottom right
1292 pixels[0] = 255;
1293 pixels[1] = 0;
1294 pixels[2] = 0;
1295 pixels[3] = 255;
1296 pixels[4] = 0;
1297 pixels[5] = 255;
1298 pixels[6] = 0;
1299 pixels[7] = 255;
1300 pixels[8] = 0;
1301 pixels[9] = 0;
1302 pixels[10] = 255;
1303 pixels[11] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00001304 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001305
1306 layer.source.buffer.buffer = buf;
1307 layer.source.buffer.textureName = texName;
1308 // Transform coordinates to only be inside the red quadrant.
Alec Mouri4049b532021-10-15 20:59:33 -07001309 layer.source.buffer.textureTransform = mat4::scale(vec4(0.2f, 0.2f, 1.f, 1.f));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001310 layer.alpha = 1.0f;
1311 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1312
Sally Qi59a9f502021-10-12 18:53:23 +00001313 layers.push_back(layer);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001314
Alec Mouric0aae732021-01-12 13:32:18 -08001315 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001316}
1317
1318void RenderEngineTest::fillBufferTextureTransform() {
1319 fillRedBufferTextureTransform();
1320 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
1321}
1322
1323void RenderEngineTest::fillRedBufferWithPremultiplyAlpha() {
1324 renderengine::DisplaySettings settings;
1325 settings.physicalDisplay = fullscreenRect();
1326 // Here logical space is 1x1
1327 settings.clip = Rect(1, 1);
1328
Sally Qi59a9f502021-10-12 18:53:23 +00001329 std::vector<renderengine::LayerSettings> layers;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001330
1331 renderengine::LayerSettings layer;
Alec Mouria90a5702021-04-16 16:36:21 +00001332 const auto buf = allocateSourceBuffer(1, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001333 uint32_t texName;
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001334 RenderEngineTest::mRE->genTextures(1, &texName);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001335 this->mTexNames.push_back(texName);
1336
1337 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00001338 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1339 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001340 pixels[0] = 255;
1341 pixels[1] = 0;
1342 pixels[2] = 0;
1343 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00001344 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001345
1346 layer.source.buffer.buffer = buf;
1347 layer.source.buffer.textureName = texName;
1348 layer.source.buffer.usePremultipliedAlpha = true;
1349 layer.alpha = 0.5f;
1350 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1351
Sally Qi59a9f502021-10-12 18:53:23 +00001352 layers.push_back(layer);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001353
Alec Mouric0aae732021-01-12 13:32:18 -08001354 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001355}
1356
1357void RenderEngineTest::fillBufferWithPremultiplyAlpha() {
1358 fillRedBufferWithPremultiplyAlpha();
1359 expectBufferColor(fullscreenRect(), 128, 0, 0, 128);
1360}
1361
1362void RenderEngineTest::fillRedBufferWithoutPremultiplyAlpha() {
1363 renderengine::DisplaySettings settings;
1364 settings.physicalDisplay = fullscreenRect();
1365 // Here logical space is 1x1
1366 settings.clip = Rect(1, 1);
1367
Sally Qi59a9f502021-10-12 18:53:23 +00001368 std::vector<renderengine::LayerSettings> layers;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001369
1370 renderengine::LayerSettings layer;
Alec Mouria90a5702021-04-16 16:36:21 +00001371 const auto buf = allocateSourceBuffer(1, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001372 uint32_t texName;
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001373 RenderEngineTest::mRE->genTextures(1, &texName);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001374 this->mTexNames.push_back(texName);
1375
1376 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00001377 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1378 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001379 pixels[0] = 255;
1380 pixels[1] = 0;
1381 pixels[2] = 0;
1382 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00001383 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001384
1385 layer.source.buffer.buffer = buf;
1386 layer.source.buffer.textureName = texName;
1387 layer.source.buffer.usePremultipliedAlpha = false;
1388 layer.alpha = 0.5f;
1389 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1390
Sally Qi59a9f502021-10-12 18:53:23 +00001391 layers.push_back(layer);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001392
Alec Mouric0aae732021-01-12 13:32:18 -08001393 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001394}
1395
1396void RenderEngineTest::fillBufferWithoutPremultiplyAlpha() {
1397 fillRedBufferWithoutPremultiplyAlpha();
wukui16f3c0bb2020-08-05 20:35:29 +08001398 expectBufferColor(fullscreenRect(), 128, 0, 0, 128, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001399}
1400
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001401template <typename SourceVariant>
1402void RenderEngineTest::drawShadow(const renderengine::LayerSettings& castingLayer,
1403 const renderengine::ShadowSettings& shadow,
1404 const ubyte4& casterColor, const ubyte4& backgroundColor) {
1405 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001406 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001407 settings.physicalDisplay = fullscreenRect();
1408 settings.clip = fullscreenRect();
1409
Sally Qi59a9f502021-10-12 18:53:23 +00001410 std::vector<renderengine::LayerSettings> layers;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001411
1412 // add background layer
1413 renderengine::LayerSettings bgLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001414 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001415 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1416 ColorSourceVariant::fillColor(bgLayer, backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1417 backgroundColor.b / 255.0f, this);
1418 bgLayer.alpha = backgroundColor.a / 255.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001419 layers.push_back(bgLayer);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001420
1421 // add shadow layer
1422 renderengine::LayerSettings shadowLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001423 shadowLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001424 shadowLayer.geometry.boundaries = castingLayer.geometry.boundaries;
1425 shadowLayer.alpha = castingLayer.alpha;
1426 shadowLayer.shadow = shadow;
Sally Qi59a9f502021-10-12 18:53:23 +00001427 layers.push_back(shadowLayer);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001428
1429 // add layer casting the shadow
1430 renderengine::LayerSettings layer = castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001431 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001432 SourceVariant::fillColor(layer, casterColor.r / 255.0f, casterColor.g / 255.0f,
1433 casterColor.b / 255.0f, this);
Sally Qi59a9f502021-10-12 18:53:23 +00001434 layers.push_back(layer);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001435
Alec Mouric0aae732021-01-12 13:32:18 -08001436 invokeDraw(settings, layers);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001437}
1438
Alec Mouribd17b3b2020-12-17 11:08:30 -08001439void RenderEngineTest::drawShadowWithoutCaster(const FloatRect& castingBounds,
1440 const renderengine::ShadowSettings& shadow,
1441 const ubyte4& backgroundColor) {
1442 renderengine::DisplaySettings settings;
1443 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1444 settings.physicalDisplay = fullscreenRect();
1445 settings.clip = fullscreenRect();
1446
Sally Qi59a9f502021-10-12 18:53:23 +00001447 std::vector<renderengine::LayerSettings> layers;
Alec Mouribd17b3b2020-12-17 11:08:30 -08001448
1449 // add background layer
1450 renderengine::LayerSettings bgLayer;
1451 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1452 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1453 ColorSourceVariant::fillColor(bgLayer, backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1454 backgroundColor.b / 255.0f, this);
1455 bgLayer.alpha = backgroundColor.a / 255.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001456 layers.push_back(bgLayer);
Alec Mouribd17b3b2020-12-17 11:08:30 -08001457
1458 // add shadow layer
1459 renderengine::LayerSettings shadowLayer;
1460 shadowLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1461 shadowLayer.geometry.boundaries = castingBounds;
Derek Sollenbergerc31985e2021-05-18 16:38:17 -04001462 shadowLayer.skipContentDraw = true;
Alec Mouribd17b3b2020-12-17 11:08:30 -08001463 shadowLayer.alpha = 1.0f;
1464 ColorSourceVariant::fillColor(shadowLayer, 0, 0, 0, this);
1465 shadowLayer.shadow = shadow;
Sally Qi59a9f502021-10-12 18:53:23 +00001466 layers.push_back(shadowLayer);
Alec Mouribd17b3b2020-12-17 11:08:30 -08001467
Alec Mouric0aae732021-01-12 13:32:18 -08001468 invokeDraw(settings, layers);
Alec Mouribd17b3b2020-12-17 11:08:30 -08001469}
1470
Alec Mouri5a493722022-01-26 16:43:02 -08001471void RenderEngineTest::tonemap(ui::Dataspace sourceDataspace, std::function<vec3(vec3)> eotf,
1472 std::function<vec3(vec3, float)> scaleOotf) {
1473 constexpr int32_t kGreyLevels = 256;
1474
1475 const auto rect = Rect(0, 0, kGreyLevels, 1);
1476
1477 constexpr float kMaxLuminance = 750.f;
1478 constexpr float kCurrentLuminanceNits = 500.f;
1479 const renderengine::DisplaySettings display{
1480 .physicalDisplay = rect,
1481 .clip = rect,
1482 .maxLuminance = kMaxLuminance,
1483 .currentLuminanceNits = kCurrentLuminanceNits,
1484 .outputDataspace = ui::Dataspace::DISPLAY_P3,
1485 };
1486
1487 auto buf = std::make_shared<
1488 renderengine::impl::
1489 ExternalTexture>(new GraphicBuffer(kGreyLevels, 1, HAL_PIXEL_FORMAT_RGBA_8888,
1490 1,
1491 GRALLOC_USAGE_SW_READ_OFTEN |
1492 GRALLOC_USAGE_SW_WRITE_OFTEN |
1493 GRALLOC_USAGE_HW_RENDER |
1494 GRALLOC_USAGE_HW_TEXTURE,
1495 "input"),
1496 *mRE,
1497 renderengine::impl::ExternalTexture::Usage::READABLE |
1498 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
1499 ASSERT_EQ(0, buf->getBuffer()->initCheck());
1500 {
1501 uint8_t* pixels;
1502 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1503 reinterpret_cast<void**>(&pixels));
1504
1505 uint8_t color = 0;
1506 for (int32_t j = 0; j < buf->getBuffer()->getHeight(); j++) {
1507 uint8_t* dest = pixels + (buf->getBuffer()->getStride() * j * 4);
1508 for (int32_t i = 0; i < buf->getBuffer()->getWidth(); i++) {
1509 dest[0] = color;
1510 dest[1] = color;
1511 dest[2] = color;
1512 dest[3] = 255;
1513 color++;
1514 dest += 4;
1515 }
1516 }
1517 buf->getBuffer()->unlock();
1518 }
1519
1520 mBuffer = std::make_shared<
1521 renderengine::impl::
1522 ExternalTexture>(new GraphicBuffer(kGreyLevels, 1, HAL_PIXEL_FORMAT_RGBA_8888,
1523 1,
1524 GRALLOC_USAGE_SW_READ_OFTEN |
1525 GRALLOC_USAGE_SW_WRITE_OFTEN |
1526 GRALLOC_USAGE_HW_RENDER |
1527 GRALLOC_USAGE_HW_TEXTURE,
1528 "output"),
1529 *mRE,
1530 renderengine::impl::ExternalTexture::Usage::READABLE |
1531 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
1532 ASSERT_EQ(0, mBuffer->getBuffer()->initCheck());
1533
1534 const renderengine::LayerSettings layer{.geometry.boundaries = rect.toFloatRect(),
1535 .source =
1536 renderengine::PixelSource{
1537 .buffer =
1538 renderengine::Buffer{
1539 .buffer =
1540 std::move(buf),
1541 .usePremultipliedAlpha =
1542 true,
1543 },
1544 },
1545 .alpha = 1.0f,
1546 .sourceDataspace = sourceDataspace};
1547
1548 std::vector<renderengine::LayerSettings> layers{layer};
1549 invokeDraw(display, layers);
1550
1551 ColorSpace displayP3 = ColorSpace::DisplayP3();
1552 ColorSpace bt2020 = ColorSpace::BT2020();
1553
1554 tonemap::Metadata metadata{.displayMaxLuminance = 750.0f};
1555
1556 auto generator = [=](Point location) {
1557 const double normColor = static_cast<double>(location.x) / (kGreyLevels - 1);
1558 const vec3 rgb = vec3(normColor, normColor, normColor);
1559
1560 const vec3 linearRGB = eotf(rgb);
1561
1562 const vec3 xyz = bt2020.getRGBtoXYZ() * linearRGB;
1563
1564 const vec3 scaledXYZ = scaleOotf(xyz, kCurrentLuminanceNits);
1565 const double gain =
1566 tonemap::getToneMapper()
1567 ->lookupTonemapGain(static_cast<aidl::android::hardware::graphics::common::
1568 Dataspace>(sourceDataspace),
1569 static_cast<aidl::android::hardware::graphics::common::
1570 Dataspace>(
1571 ui::Dataspace::DISPLAY_P3),
1572 scaleOotf(linearRGB, kCurrentLuminanceNits), scaledXYZ,
1573 metadata);
1574 const vec3 normalizedXYZ = scaledXYZ * gain / metadata.displayMaxLuminance;
1575
1576 const vec3 targetRGB = OETF_sRGB(displayP3.getXYZtoRGB() * normalizedXYZ) * 255;
1577 return ubyte4(static_cast<uint8_t>(targetRGB.r), static_cast<uint8_t>(targetRGB.g),
1578 static_cast<uint8_t>(targetRGB.b), 255);
1579 };
1580
1581 expectBufferColor(Rect(kGreyLevels, 1), generator, 2);
1582}
1583
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001584INSTANTIATE_TEST_SUITE_P(PerRenderEngineType, RenderEngineTest,
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001585 testing::Values(std::make_shared<GLESRenderEngineFactory>(),
Alec Mouri0eab3e82020-12-08 18:10:27 -08001586 std::make_shared<GLESCMRenderEngineFactory>(),
1587 std::make_shared<SkiaGLESRenderEngineFactory>(),
1588 std::make_shared<SkiaGLESCMRenderEngineFactory>()));
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001589
1590TEST_P(RenderEngineTest, drawLayers_noLayersToDraw) {
Alec Mouric0aae732021-01-12 13:32:18 -08001591 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001592 drawEmptyLayers();
1593}
1594
Ana Krulec07b98df2021-01-07 14:38:40 -08001595TEST_P(RenderEngineTest, drawLayers_withoutBuffers_withColorTransform) {
Alec Mouria90a5702021-04-16 16:36:21 +00001596 initializeRenderEngine();
Ana Krulec07b98df2021-01-07 14:38:40 -08001597
1598 renderengine::DisplaySettings settings;
1599 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1600 settings.physicalDisplay = fullscreenRect();
1601 settings.clip = fullscreenRect();
1602
1603 // 255, 255, 255, 255 is full opaque white.
Alec Mouri4049b532021-10-15 20:59:33 -07001604 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
1605 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Ana Krulec07b98df2021-01-07 14:38:40 -08001606 // Create layer with given color.
1607 renderengine::LayerSettings bgLayer;
1608 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1609 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1610 bgLayer.source.solidColor = half3(backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1611 backgroundColor.b / 255.0f);
1612 bgLayer.alpha = backgroundColor.a / 255.0f;
1613 // Transform the red color.
1614 bgLayer.colorTransform = mat4(-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
1615
Sally Qi59a9f502021-10-12 18:53:23 +00001616 std::vector<renderengine::LayerSettings> layers;
1617 layers.push_back(bgLayer);
Ana Krulec07b98df2021-01-07 14:38:40 -08001618
Alec Mouric0aae732021-01-12 13:32:18 -08001619 invokeDraw(settings, layers);
Ana Krulec07b98df2021-01-07 14:38:40 -08001620
1621 // Expect to see full opaque pixel (with inverted red from the transform).
Alec Mouric0aae732021-01-12 13:32:18 -08001622 expectBufferColor(Rect(0, 0, 10, 10), 0.f, backgroundColor.g, backgroundColor.b,
Ana Krulec07b98df2021-01-07 14:38:40 -08001623 backgroundColor.a);
1624}
1625
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001626TEST_P(RenderEngineTest, drawLayers_nullOutputBuffer) {
Alec Mouric0aae732021-01-12 13:32:18 -08001627 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001628
Alec Mourid43ccab2019-03-13 12:23:45 -07001629 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001630 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Sally Qi59a9f502021-10-12 18:53:23 +00001631 std::vector<renderengine::LayerSettings> layers;
Alec Mourid43ccab2019-03-13 12:23:45 -07001632 renderengine::LayerSettings layer;
1633 layer.geometry.boundaries = fullscreenRect().toFloatRect();
1634 BufferSourceVariant<ForceOpaqueBufferVariant>::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
Sally Qi59a9f502021-10-12 18:53:23 +00001635 layers.push_back(layer);
Sally Qi4cabdd02021-08-05 16:45:57 -07001636 std::future<renderengine::RenderEngineResult> result =
1637 mRE->drawLayers(settings, layers, nullptr, true, base::unique_fd());
Alec Mourid43ccab2019-03-13 12:23:45 -07001638
Sally Qi4cabdd02021-08-05 16:45:57 -07001639 ASSERT_TRUE(result.valid());
Derek Sollenbergerec411212021-08-25 10:54:47 -04001640 auto [status, fence] = result.get();
Alec Mourid43ccab2019-03-13 12:23:45 -07001641 ASSERT_EQ(BAD_VALUE, status);
Derek Sollenbergerec411212021-08-25 10:54:47 -04001642 ASSERT_FALSE(fence.ok());
Alec Mourid43ccab2019-03-13 12:23:45 -07001643}
1644
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001645TEST_P(RenderEngineTest, drawLayers_doesNotCacheFramebuffer) {
1646 const auto& renderEngineFactory = GetParam();
Alec Mouric0aae732021-01-12 13:32:18 -08001647
1648 if (renderEngineFactory->type() != renderengine::RenderEngine::RenderEngineType::GLES) {
1649 // GLES-specific test
1650 return;
1651 }
1652
1653 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001654
Alec Mourife0d72b2019-03-21 14:05:56 -07001655 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001656 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourife0d72b2019-03-21 14:05:56 -07001657 settings.physicalDisplay = fullscreenRect();
1658 settings.clip = fullscreenRect();
1659
Sally Qi59a9f502021-10-12 18:53:23 +00001660 std::vector<renderengine::LayerSettings> layers;
Alec Mourife0d72b2019-03-21 14:05:56 -07001661 renderengine::LayerSettings layer;
1662 layer.geometry.boundaries = fullscreenRect().toFloatRect();
1663 BufferSourceVariant<ForceOpaqueBufferVariant>::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
1664 layer.alpha = 1.0;
Sally Qi59a9f502021-10-12 18:53:23 +00001665 layers.push_back(layer);
Alec Mourife0d72b2019-03-21 14:05:56 -07001666
Sally Qi4cabdd02021-08-05 16:45:57 -07001667 std::future<renderengine::RenderEngineResult> result =
1668 mRE->drawLayers(settings, layers, mBuffer, false, base::unique_fd());
1669 ASSERT_TRUE(result.valid());
Derek Sollenbergerec411212021-08-25 10:54:47 -04001670 auto [status, fence] = result.get();
1671
Alec Mourife0d72b2019-03-21 14:05:56 -07001672 ASSERT_EQ(NO_ERROR, status);
Derek Sollenbergerec411212021-08-25 10:54:47 -04001673 if (fence.ok()) {
1674 sync_wait(fence.get(), -1);
1675 }
1676
Alec Mouria90a5702021-04-16 16:36:21 +00001677 ASSERT_FALSE(mGLESRE->isFramebufferImageCachedForTesting(mBuffer->getBuffer()->getId()));
Alec Mourife0d72b2019-03-21 14:05:56 -07001678 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
1679}
1680
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001681TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001682 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001683 fillRedBuffer<ColorSourceVariant>();
1684}
1685
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001686TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001687 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001688 fillGreenBuffer<ColorSourceVariant>();
1689}
1690
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001691TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001692 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001693 fillBlueBuffer<ColorSourceVariant>();
1694}
1695
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001696TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001697 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001698 fillRedTransparentBuffer<ColorSourceVariant>();
1699}
1700
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001701TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001702 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001703 fillBufferPhysicalOffset<ColorSourceVariant>();
1704}
1705
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001706TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001707 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001708 fillBufferCheckersRotate0<ColorSourceVariant>();
1709}
1710
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001711TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001712 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001713 fillBufferCheckersRotate90<ColorSourceVariant>();
1714}
1715
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001716TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001717 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001718 fillBufferCheckersRotate180<ColorSourceVariant>();
1719}
1720
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001721TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001722 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001723 fillBufferCheckersRotate270<ColorSourceVariant>();
1724}
1725
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001726TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001727 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001728 fillBufferLayerTransform<ColorSourceVariant>();
1729}
1730
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001731TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001732 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08001733 fillBufferColorTransform<ColorSourceVariant>();
1734}
1735
Sally Qi2019fd22021-11-22 10:19:04 -08001736TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_sourceDataspace) {
1737 const auto& renderEngineFactory = GetParam();
1738 // skip for non color management
1739 if (!renderEngineFactory->useColorManagement()) {
1740 return;
1741 }
1742 // skip for GLESRenderEngine
1743 if (renderEngineFactory->type() != renderengine::RenderEngine::RenderEngineType::GLES) {
1744 return;
1745 }
1746
1747 initializeRenderEngine();
1748 fillBufferColorTransformAndSourceDataspace<ColorSourceVariant>();
1749}
1750
1751TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_outputDataspace) {
1752 const auto& renderEngineFactory = GetParam();
1753 // skip for non color management
1754 if (!renderEngineFactory->useColorManagement()) {
1755 return;
1756 }
1757 // skip for GLESRenderEngine
1758 if (renderEngineFactory->type() != renderengine::RenderEngine::RenderEngineType::GLES) {
1759 return;
1760 }
1761
1762 initializeRenderEngine();
1763 fillBufferColorTransformAndOutputDataspace<ColorSourceVariant>();
1764}
1765
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001766TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001767 initializeRenderEngine();
Alec Mouri7c94edb2018-12-03 21:23:26 -08001768 fillBufferWithRoundedCorners<ColorSourceVariant>();
1769}
1770
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001771TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001772 initializeRenderEngine();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001773 fillBufferColorTransformZeroLayerAlpha<ColorSourceVariant>();
1774}
1775
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001776TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001777 initializeRenderEngine();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001778 fillBufferAndBlurBackground<ColorSourceVariant>();
1779}
1780
Alec Mourie8489fd2021-04-29 16:08:56 -07001781TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_colorSource) {
1782 initializeRenderEngine();
1783 fillSmallLayerAndBlurBackground<ColorSourceVariant>();
1784}
1785
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001786TEST_P(RenderEngineTest, drawLayers_overlayCorners_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001787 initializeRenderEngine();
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001788 overlayCorners<ColorSourceVariant>();
1789}
1790
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001791TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001792 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001793 fillRedBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1794}
1795
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001796TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001797 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001798 fillGreenBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1799}
1800
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001801TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001802 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001803 fillBlueBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1804}
1805
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001806TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001807 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001808 fillRedTransparentBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1809}
1810
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001811TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001812 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001813 fillBufferPhysicalOffset<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1814}
1815
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001816TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001817 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001818 fillBufferCheckersRotate0<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1819}
1820
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001821TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001822 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001823 fillBufferCheckersRotate90<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1824}
1825
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001826TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001827 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001828 fillBufferCheckersRotate180<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1829}
1830
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001831TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001832 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001833 fillBufferCheckersRotate270<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1834}
1835
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001836TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001837 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001838 fillBufferLayerTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1839}
1840
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001841TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001842 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08001843 fillBufferColorTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1844}
1845
Sally Qi2019fd22021-11-22 10:19:04 -08001846TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndSourceDataspace_opaqueBufferSource) {
1847 const auto& renderEngineFactory = GetParam();
1848 // skip for non color management
1849 if (!renderEngineFactory->useColorManagement()) {
1850 return;
1851 }
1852 // skip for GLESRenderEngine
1853 if (renderEngineFactory->type() != renderengine::RenderEngine::RenderEngineType::GLES) {
1854 return;
1855 }
1856
1857 initializeRenderEngine();
1858 fillBufferColorTransformAndSourceDataspace<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1859}
1860
1861TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndOutputDataspace_opaqueBufferSource) {
1862 const auto& renderEngineFactory = GetParam();
1863 // skip for non color management
1864 if (!renderEngineFactory->useColorManagement()) {
1865 return;
1866 }
1867 // skip for GLESRenderEngine
1868 if (renderEngineFactory->type() != renderengine::RenderEngine::RenderEngineType::GLES) {
1869 return;
1870 }
1871
1872 initializeRenderEngine();
1873 fillBufferColorTransformAndOutputDataspace<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1874}
1875
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001876TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001877 initializeRenderEngine();
Alec Mouri7c94edb2018-12-03 21:23:26 -08001878 fillBufferWithRoundedCorners<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1879}
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001880
Alec Mouric0aae732021-01-12 13:32:18 -08001881TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_opaqueBufferSource) {
1882 initializeRenderEngine();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001883 fillBufferColorTransformZeroLayerAlpha<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1884}
Alec Mouri7c94edb2018-12-03 21:23:26 -08001885
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001886TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001887 initializeRenderEngine();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001888 fillBufferAndBlurBackground<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1889}
1890
Alec Mourie8489fd2021-04-29 16:08:56 -07001891TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_opaqueBufferSource) {
1892 initializeRenderEngine();
1893 fillSmallLayerAndBlurBackground<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1894}
1895
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001896TEST_P(RenderEngineTest, drawLayers_overlayCorners_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001897 initializeRenderEngine();
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001898 overlayCorners<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1899}
1900
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001901TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001902 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001903 fillRedBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1904}
1905
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001906TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001907 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001908 fillGreenBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1909}
1910
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001911TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001912 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001913 fillBlueBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1914}
1915
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001916TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001917 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001918 fillRedTransparentBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1919}
1920
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001921TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001922 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001923 fillBufferPhysicalOffset<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1924}
1925
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001926TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001927 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001928 fillBufferCheckersRotate0<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1929}
1930
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001931TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001932 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001933 fillBufferCheckersRotate90<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1934}
1935
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001936TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001937 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001938 fillBufferCheckersRotate180<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1939}
1940
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001941TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001942 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001943 fillBufferCheckersRotate270<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1944}
1945
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001946TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001947 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001948 fillBufferLayerTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1949}
1950
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001951TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001952 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08001953 fillBufferColorTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1954}
1955
Sally Qi2019fd22021-11-22 10:19:04 -08001956TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndSourceDataspace_bufferSource) {
1957 const auto& renderEngineFactory = GetParam();
1958 // skip for non color management
1959 if (!renderEngineFactory->useColorManagement()) {
1960 return;
1961 }
1962 // skip for GLESRenderEngine
1963 if (renderEngineFactory->type() != renderengine::RenderEngine::RenderEngineType::GLES) {
1964 return;
1965 }
1966
1967 initializeRenderEngine();
1968 fillBufferColorTransformAndSourceDataspace<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1969}
1970
1971TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndOutputDataspace_bufferSource) {
1972 const auto& renderEngineFactory = GetParam();
1973 // skip for non color management
1974 if (!renderEngineFactory->useColorManagement()) {
1975 return;
1976 }
1977 // skip for GLESRenderEngine
1978 if (renderEngineFactory->type() != renderengine::RenderEngine::RenderEngineType::GLES) {
1979 return;
1980 }
1981
1982 initializeRenderEngine();
1983 fillBufferColorTransformAndOutputDataspace<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1984}
1985
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001986TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001987 initializeRenderEngine();
Alec Mouri7c94edb2018-12-03 21:23:26 -08001988 fillBufferWithRoundedCorners<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1989}
1990
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001991TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001992 initializeRenderEngine();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001993 fillBufferColorTransformZeroLayerAlpha<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1994}
1995
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001996TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001997 initializeRenderEngine();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001998 fillBufferAndBlurBackground<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1999}
2000
Alec Mourie8489fd2021-04-29 16:08:56 -07002001TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_bufferSource) {
2002 initializeRenderEngine();
2003 fillSmallLayerAndBlurBackground<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2004}
2005
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002006TEST_P(RenderEngineTest, drawLayers_overlayCorners_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08002007 initializeRenderEngine();
Alec Mourie7d1d4a2019-02-05 01:13:46 +00002008 overlayCorners<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2009}
2010
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002011TEST_P(RenderEngineTest, drawLayers_fillBufferTextureTransform) {
Alec Mouric0aae732021-01-12 13:32:18 -08002012 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002013 fillBufferTextureTransform();
2014}
2015
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002016TEST_P(RenderEngineTest, drawLayers_fillBuffer_premultipliesAlpha) {
Alec Mouric0aae732021-01-12 13:32:18 -08002017 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002018 fillBufferWithPremultiplyAlpha();
2019}
2020
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002021TEST_P(RenderEngineTest, drawLayers_fillBuffer_withoutPremultiplyingAlpha) {
Alec Mouric0aae732021-01-12 13:32:18 -08002022 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08002023 fillBufferWithoutPremultiplyAlpha();
2024}
2025
Alec Mouribd17b3b2020-12-17 11:08:30 -08002026TEST_P(RenderEngineTest, drawLayers_fillShadow_castsWithoutCasterLayer) {
Alec Mouric0aae732021-01-12 13:32:18 -08002027 initializeRenderEngine();
Alec Mouribd17b3b2020-12-17 11:08:30 -08002028
Alec Mouri4049b532021-10-15 20:59:33 -07002029 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2030 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Alec Mouribd17b3b2020-12-17 11:08:30 -08002031 const float shadowLength = 5.0f;
2032 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2033 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2034 renderengine::ShadowSettings settings =
2035 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2036 false /* casterIsTranslucent */);
2037
2038 drawShadowWithoutCaster(casterBounds.toFloatRect(), settings, backgroundColor);
2039 expectShadowColorWithoutCaster(casterBounds.toFloatRect(), settings, backgroundColor);
2040}
2041
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002042TEST_P(RenderEngineTest, drawLayers_fillShadow_casterLayerMinSize) {
Alec Mouric0aae732021-01-12 13:32:18 -08002043 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002044
Alec Mouri4049b532021-10-15 20:59:33 -07002045 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2046 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2047 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2048 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002049 const float shadowLength = 5.0f;
2050 Rect casterBounds(1, 1);
2051 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2052 renderengine::LayerSettings castingLayer;
2053 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2054 castingLayer.alpha = 1.0f;
2055 renderengine::ShadowSettings settings =
2056 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2057 false /* casterIsTranslucent */);
2058
2059 drawShadow<ColorSourceVariant>(castingLayer, settings, casterColor, backgroundColor);
2060 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2061}
2062
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002063TEST_P(RenderEngineTest, drawLayers_fillShadow_casterColorLayer) {
Alec Mouric0aae732021-01-12 13:32:18 -08002064 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002065
Alec Mouri4049b532021-10-15 20:59:33 -07002066 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2067 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2068 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2069 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002070 const float shadowLength = 5.0f;
2071 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2072 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2073 renderengine::LayerSettings castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002074 castingLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002075 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2076 castingLayer.alpha = 1.0f;
2077 renderengine::ShadowSettings settings =
2078 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2079 false /* casterIsTranslucent */);
2080
2081 drawShadow<ColorSourceVariant>(castingLayer, settings, casterColor, backgroundColor);
2082 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2083}
2084
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002085TEST_P(RenderEngineTest, drawLayers_fillShadow_casterOpaqueBufferLayer) {
Alec Mouric0aae732021-01-12 13:32:18 -08002086 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002087
Alec Mouri4049b532021-10-15 20:59:33 -07002088 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2089 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2090 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2091 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002092 const float shadowLength = 5.0f;
2093 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2094 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2095 renderengine::LayerSettings castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002096 castingLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002097 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2098 castingLayer.alpha = 1.0f;
2099 renderengine::ShadowSettings settings =
2100 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2101 false /* casterIsTranslucent */);
2102
2103 drawShadow<BufferSourceVariant<ForceOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2104 backgroundColor);
2105 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2106}
2107
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002108TEST_P(RenderEngineTest, drawLayers_fillShadow_casterWithRoundedCorner) {
Alec Mouric0aae732021-01-12 13:32:18 -08002109 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002110
Alec Mouri4049b532021-10-15 20:59:33 -07002111 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2112 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2113 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2114 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002115 const float shadowLength = 5.0f;
2116 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2117 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2118 renderengine::LayerSettings castingLayer;
2119 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2120 castingLayer.geometry.roundedCornersRadius = 3.0f;
2121 castingLayer.geometry.roundedCornersCrop = casterBounds.toFloatRect();
2122 castingLayer.alpha = 1.0f;
2123 renderengine::ShadowSettings settings =
2124 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2125 false /* casterIsTranslucent */);
2126
2127 drawShadow<BufferSourceVariant<ForceOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2128 backgroundColor);
2129 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2130}
2131
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002132TEST_P(RenderEngineTest, drawLayers_fillShadow_translucentCasterWithAlpha) {
Alec Mouric0aae732021-01-12 13:32:18 -08002133 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002134
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002135 const ubyte4 casterColor(255, 0, 0, 255);
2136 const ubyte4 backgroundColor(255, 255, 255, 255);
2137 const float shadowLength = 5.0f;
2138 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2139 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2140 renderengine::LayerSettings castingLayer;
2141 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2142 castingLayer.alpha = 0.5f;
2143 renderengine::ShadowSettings settings =
2144 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2145 true /* casterIsTranslucent */);
2146
2147 drawShadow<BufferSourceVariant<RelaxOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2148 backgroundColor);
2149
2150 // verify only the background since the shadow will draw behind the caster
2151 const float shadowInset = settings.length * -1.0f;
2152 const Rect casterWithShadow =
2153 Rect(casterBounds).inset(shadowInset, shadowInset, shadowInset, shadowInset);
2154 const Region backgroundRegion = Region(fullscreenRect()).subtractSelf(casterWithShadow);
2155 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
2156 backgroundColor.a);
2157}
2158
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002159TEST_P(RenderEngineTest, cleanupPostRender_cleansUpOnce) {
Alec Mouric0aae732021-01-12 13:32:18 -08002160 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002161
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002162 renderengine::DisplaySettings settings;
2163 settings.physicalDisplay = fullscreenRect();
2164 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002165 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002166
Sally Qi59a9f502021-10-12 18:53:23 +00002167 std::vector<renderengine::LayerSettings> layers;
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002168 renderengine::LayerSettings layer;
2169 layer.geometry.boundaries = fullscreenRect().toFloatRect();
2170 BufferSourceVariant<ForceOpaqueBufferVariant>::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
2171 layer.alpha = 1.0;
Sally Qi59a9f502021-10-12 18:53:23 +00002172 layers.push_back(layer);
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002173
Sally Qi4cabdd02021-08-05 16:45:57 -07002174 std::future<renderengine::RenderEngineResult> resultOne =
2175 mRE->drawLayers(settings, layers, mBuffer, true, base::unique_fd());
2176 ASSERT_TRUE(resultOne.valid());
2177 auto [statusOne, fenceOne] = resultOne.get();
2178 ASSERT_EQ(NO_ERROR, statusOne);
2179
2180 std::future<renderengine::RenderEngineResult> resultTwo =
2181 mRE->drawLayers(settings, layers, mBuffer, true, std::move(fenceOne));
2182 ASSERT_TRUE(resultTwo.valid());
2183 auto [statusTwo, fenceTwo] = resultTwo.get();
2184 ASSERT_EQ(NO_ERROR, statusTwo);
Derek Sollenbergerec411212021-08-25 10:54:47 -04002185 if (fenceTwo.ok()) {
2186 sync_wait(fenceTwo.get(), -1);
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002187 }
Derek Sollenbergerec411212021-08-25 10:54:47 -04002188
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002189 // Only cleanup the first time.
Derek Sollenbergerd3f60652021-06-11 15:34:36 -04002190 EXPECT_FALSE(mRE->canSkipPostRenderCleanup());
2191 mRE->cleanupPostRender();
2192 EXPECT_TRUE(mRE->canSkipPostRenderCleanup());
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002193}
2194
Ana Krulecf9a15d92020-12-11 08:35:00 -08002195TEST_P(RenderEngineTest, testRoundedCornersCrop) {
Alec Mouric0aae732021-01-12 13:32:18 -08002196 initializeRenderEngine();
Ana Krulecf9a15d92020-12-11 08:35:00 -08002197
2198 renderengine::DisplaySettings settings;
2199 settings.physicalDisplay = fullscreenRect();
2200 settings.clip = fullscreenRect();
2201 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2202
Sally Qi59a9f502021-10-12 18:53:23 +00002203 std::vector<renderengine::LayerSettings> layers;
Ana Krulecf9a15d92020-12-11 08:35:00 -08002204
2205 renderengine::LayerSettings redLayer;
2206 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2207 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
2208 redLayer.geometry.roundedCornersRadius = 5.0f;
2209 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2210 // Red background.
2211 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2212 redLayer.alpha = 1.0f;
2213
Sally Qi59a9f502021-10-12 18:53:23 +00002214 layers.push_back(redLayer);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002215
2216 // Green layer with 1/3 size.
2217 renderengine::LayerSettings greenLayer;
2218 greenLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2219 greenLayer.geometry.boundaries = fullscreenRect().toFloatRect();
2220 greenLayer.geometry.roundedCornersRadius = 5.0f;
2221 // Bottom right corner is not going to be rounded.
2222 greenLayer.geometry.roundedCornersCrop =
2223 Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3, DEFAULT_DISPLAY_HEIGHT,
2224 DEFAULT_DISPLAY_HEIGHT)
2225 .toFloatRect();
2226 greenLayer.source.solidColor = half3(0.0f, 1.0f, 0.0f);
2227 greenLayer.alpha = 1.0f;
2228
Sally Qi59a9f502021-10-12 18:53:23 +00002229 layers.push_back(greenLayer);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002230
Alec Mouric0aae732021-01-12 13:32:18 -08002231 invokeDraw(settings, layers);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002232
2233 // Corners should be ignored...
2234 // Screen size: width is 128, height is 256.
2235 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 0);
2236 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, 0, DEFAULT_DISPLAY_WIDTH, 1), 0, 0, 0, 0);
2237 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT - 1, 1, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
2238 // Bottom right corner is kept out of the clipping, and it's green.
2239 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1,
2240 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
2241 0, 255, 0, 255);
2242}
2243
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002244TEST_P(RenderEngineTest, testRoundedCornersParentCrop) {
2245 initializeRenderEngine();
2246
2247 renderengine::DisplaySettings settings;
2248 settings.physicalDisplay = fullscreenRect();
2249 settings.clip = fullscreenRect();
2250 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2251
Sally Qi59a9f502021-10-12 18:53:23 +00002252 std::vector<renderengine::LayerSettings> layers;
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002253
2254 renderengine::LayerSettings redLayer;
2255 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2256 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
2257 redLayer.geometry.roundedCornersRadius = 5.0f;
2258 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);
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002264
2265 // Green layer with 1/2 size with parent crop rect.
2266 renderengine::LayerSettings greenLayer = redLayer;
2267 greenLayer.geometry.boundaries =
2268 FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT / 2);
2269 greenLayer.source.solidColor = half3(0.0f, 1.0f, 0.0f);
2270
Sally Qi59a9f502021-10-12 18:53:23 +00002271 layers.push_back(greenLayer);
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002272
2273 invokeDraw(settings, layers);
2274
2275 // Due to roundedCornersRadius, the corners are untouched.
2276 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2277 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2278 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2279 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2280
2281 // top middle should be green and the bottom middle red
2282 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, 0), 0, 255, 0, 255);
2283 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0, 255);
2284
2285 // the bottom edge of the green layer should not be rounded
2286 expectBufferColor(Point(0, (DEFAULT_DISPLAY_HEIGHT / 2) - 1), 0, 255, 0, 255);
2287}
2288
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002289TEST_P(RenderEngineTest, testRoundedCornersParentCropSmallBounds) {
2290 initializeRenderEngine();
2291
2292 renderengine::DisplaySettings settings;
2293 settings.physicalDisplay = fullscreenRect();
2294 settings.clip = fullscreenRect();
2295 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2296
Sally Qi59a9f502021-10-12 18:53:23 +00002297 std::vector<renderengine::LayerSettings> layers;
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002298
2299 renderengine::LayerSettings redLayer;
2300 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2301 redLayer.geometry.boundaries = FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, 32);
2302 redLayer.geometry.roundedCornersRadius = 64;
2303 redLayer.geometry.roundedCornersCrop = FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, 128);
2304 // Red background.
2305 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2306 redLayer.alpha = 1.0f;
2307
Sally Qi59a9f502021-10-12 18:53:23 +00002308 layers.push_back(redLayer);
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002309 invokeDraw(settings, layers);
2310
2311 // Due to roundedCornersRadius, the top corners are untouched.
2312 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2313 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2314
2315 // ensure that the entire height of the red layer was clipped by the rounded corners crop.
2316 expectBufferColor(Point(0, 31), 0, 0, 0, 0);
2317 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 31), 0, 0, 0, 0);
2318
2319 // the bottom middle should be red
2320 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, 31), 255, 0, 0, 255);
2321}
2322
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002323TEST_P(RenderEngineTest, testClear) {
2324 initializeRenderEngine();
2325
2326 const auto rect = fullscreenRect();
2327 const renderengine::DisplaySettings display{
2328 .physicalDisplay = rect,
2329 .clip = rect,
2330 };
2331
2332 const renderengine::LayerSettings redLayer{
2333 .geometry.boundaries = rect.toFloatRect(),
2334 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
2335 .alpha = 1.0f,
2336 };
2337
2338 // This mimics prepareClearClientComposition. This layer should overwrite
2339 // the redLayer, so that the buffer is transparent, rather than red.
2340 const renderengine::LayerSettings clearLayer{
2341 .geometry.boundaries = rect.toFloatRect(),
2342 .source.solidColor = half3(0.0f, 0.0f, 0.0f),
2343 .alpha = 0.0f,
2344 .disableBlending = true,
2345 };
2346
Sally Qi59a9f502021-10-12 18:53:23 +00002347 std::vector<renderengine::LayerSettings> layers{redLayer, clearLayer};
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002348 invokeDraw(display, layers);
2349 expectBufferColor(rect, 0, 0, 0, 0);
2350}
2351
2352TEST_P(RenderEngineTest, testDisableBlendingBuffer) {
2353 initializeRenderEngine();
2354
2355 const auto rect = Rect(0, 0, 1, 1);
2356 const renderengine::DisplaySettings display{
2357 .physicalDisplay = rect,
2358 .clip = rect,
2359 };
2360
2361 const renderengine::LayerSettings redLayer{
2362 .geometry.boundaries = rect.toFloatRect(),
2363 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
2364 .alpha = 1.0f,
2365 };
2366
2367 // The next layer will overwrite redLayer with a GraphicBuffer that is green
2368 // applied with a translucent alpha.
Alec Mouria90a5702021-04-16 16:36:21 +00002369 const auto buf = allocateSourceBuffer(1, 1);
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002370 {
2371 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00002372 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2373 reinterpret_cast<void**>(&pixels));
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002374 pixels[0] = 0;
2375 pixels[1] = 255;
2376 pixels[2] = 0;
2377 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00002378 buf->getBuffer()->unlock();
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002379 }
2380
2381 const renderengine::LayerSettings greenLayer{
2382 .geometry.boundaries = rect.toFloatRect(),
2383 .source =
2384 renderengine::PixelSource{
2385 .buffer =
2386 renderengine::Buffer{
2387 .buffer = buf,
2388 .usePremultipliedAlpha = true,
2389 },
2390 },
2391 .alpha = 0.5f,
2392 .disableBlending = true,
2393 };
2394
Sally Qi59a9f502021-10-12 18:53:23 +00002395 std::vector<renderengine::LayerSettings> layers{redLayer, greenLayer};
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002396 invokeDraw(display, layers);
2397 expectBufferColor(rect, 0, 128, 0, 128);
2398}
2399
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002400TEST_P(RenderEngineTest, testDimming) {
2401 if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) {
2402 return;
2403 }
2404 initializeRenderEngine();
2405
2406 const auto displayRect = Rect(3, 1);
2407 const renderengine::DisplaySettings display{
2408 .physicalDisplay = displayRect,
2409 .clip = displayRect,
2410 .outputDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2411 .targetLuminanceNits = 1000.f,
2412 };
2413
2414 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2415 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2416 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2417
2418 const renderengine::LayerSettings greenLayer{
2419 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2420 .source =
2421 renderengine::PixelSource{
2422 .buffer =
2423 renderengine::Buffer{
2424 .buffer = greenBuffer,
2425 .usePremultipliedAlpha = true,
2426 },
2427 },
2428 .alpha = 1.0f,
2429 .sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2430 .whitePointNits = 200.f,
2431 };
2432
2433 const renderengine::LayerSettings blueLayer{
2434 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2435 .source =
2436 renderengine::PixelSource{
2437 .buffer =
2438 renderengine::Buffer{
2439 .buffer = blueBuffer,
2440 .usePremultipliedAlpha = true,
2441 },
2442 },
2443 .alpha = 1.0f,
2444 .sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2445 .whitePointNits = 1000.f / 51.f,
2446 };
2447
2448 const renderengine::LayerSettings redLayer{
2449 .geometry.boundaries = FloatRect(2.f, 0.f, 3.f, 1.f),
2450 .source =
2451 renderengine::PixelSource{
2452 .buffer =
2453 renderengine::Buffer{
2454 .buffer = redBuffer,
2455 .usePremultipliedAlpha = true,
2456 },
2457 },
2458 .alpha = 1.0f,
2459 .sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2460 // When the white point is not set for a layer, just ignore it and treat it as the same
2461 // as the max layer
2462 .whitePointNits = -1.f,
2463 };
2464
2465 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer, redLayer};
2466 invokeDraw(display, layers);
2467
2468 expectBufferColor(Rect(1, 1), 0, 51, 0, 255, 1);
2469 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 5, 255, 1);
2470 expectBufferColor(Rect(2, 0, 3, 1), 51, 0, 0, 255, 1);
2471}
2472
2473TEST_P(RenderEngineTest, testDimming_withoutTargetLuminance) {
2474 initializeRenderEngine();
2475 if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) {
2476 return;
2477 }
2478
2479 const auto displayRect = Rect(2, 1);
2480 const renderengine::DisplaySettings display{
2481 .physicalDisplay = displayRect,
2482 .clip = displayRect,
2483 .outputDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2484 .targetLuminanceNits = -1.f,
2485 };
2486
2487 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2488 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2489
2490 const renderengine::LayerSettings greenLayer{
2491 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2492 .source =
2493 renderengine::PixelSource{
2494 .buffer =
2495 renderengine::Buffer{
2496 .buffer = greenBuffer,
2497 .usePremultipliedAlpha = true,
2498 },
2499 },
2500 .alpha = 1.0f,
2501 .sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2502 .whitePointNits = 200.f,
2503 };
2504
2505 const renderengine::LayerSettings blueLayer{
2506 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2507 .source =
2508 renderengine::PixelSource{
2509 .buffer =
2510 renderengine::Buffer{
2511 .buffer = blueBuffer,
2512 .usePremultipliedAlpha = true,
2513 },
2514 },
2515 .alpha = 1.0f,
2516 .sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2517 .whitePointNits = 1000.f,
2518 };
2519
2520 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer};
2521 invokeDraw(display, layers);
2522
2523 expectBufferColor(Rect(1, 1), 0, 51, 0, 255, 1);
2524 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 255, 255);
2525}
2526
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002527TEST_P(RenderEngineTest, test_isOpaque) {
2528 initializeRenderEngine();
2529
2530 const auto rect = Rect(0, 0, 1, 1);
2531 const renderengine::DisplaySettings display{
2532 .physicalDisplay = rect,
2533 .clip = rect,
2534 .outputDataspace = ui::Dataspace::DISPLAY_P3,
2535 };
2536
2537 // Create an unpremul buffer that is green with no alpha. Using isOpaque
2538 // should make the green show.
2539 const auto buf = allocateSourceBuffer(1, 1);
2540 {
2541 uint8_t* pixels;
2542 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2543 reinterpret_cast<void**>(&pixels));
2544 pixels[0] = 0;
2545 pixels[1] = 255;
2546 pixels[2] = 0;
2547 pixels[3] = 0;
2548 buf->getBuffer()->unlock();
2549 }
2550
2551 const renderengine::LayerSettings greenLayer{
2552 .geometry.boundaries = rect.toFloatRect(),
2553 .source =
2554 renderengine::PixelSource{
2555 .buffer =
2556 renderengine::Buffer{
2557 .buffer = buf,
2558 // Although the pixels are not
2559 // premultiplied in practice, this
2560 // matches the input we see.
2561 .usePremultipliedAlpha = true,
2562 .isOpaque = true,
2563 },
2564 },
2565 .alpha = 1.0f,
2566 };
2567
Sally Qi59a9f502021-10-12 18:53:23 +00002568 std::vector<renderengine::LayerSettings> layers{greenLayer};
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002569 invokeDraw(display, layers);
2570
2571 if (GetParam()->useColorManagement()) {
2572 expectBufferColor(rect, 117, 251, 76, 255);
2573 } else {
2574 expectBufferColor(rect, 0, 255, 0, 255);
2575 }
2576}
Alec Mouri4049b532021-10-15 20:59:33 -07002577
Alec Mouri4049b532021-10-15 20:59:33 -07002578TEST_P(RenderEngineTest, test_tonemapPQMatches) {
2579 if (!GetParam()->useColorManagement()) {
Alec Mouri5a493722022-01-26 16:43:02 -08002580 GTEST_SKIP();
Alec Mouri4049b532021-10-15 20:59:33 -07002581 }
2582
2583 if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) {
Alec Mouri5a493722022-01-26 16:43:02 -08002584 GTEST_SKIP();
Alec Mouri4049b532021-10-15 20:59:33 -07002585 }
2586
2587 initializeRenderEngine();
2588
Alec Mouri5a493722022-01-26 16:43:02 -08002589 tonemap(
2590 static_cast<ui::Dataspace>(HAL_DATASPACE_STANDARD_BT2020 |
2591 HAL_DATASPACE_TRANSFER_ST2084 | HAL_DATASPACE_RANGE_FULL),
2592 [](vec3 color) { return EOTF_PQ(color); },
2593 [](vec3 color, float) {
2594 static constexpr float kMaxPQLuminance = 10000.f;
2595 return color * kMaxPQLuminance;
2596 });
2597}
Alec Mouri4049b532021-10-15 20:59:33 -07002598
Alec Mouri5a493722022-01-26 16:43:02 -08002599TEST_P(RenderEngineTest, test_tonemapHLGMatches) {
2600 if (!GetParam()->useColorManagement()) {
2601 GTEST_SKIP();
Alec Mouri4049b532021-10-15 20:59:33 -07002602 }
2603
Alec Mouri5a493722022-01-26 16:43:02 -08002604 if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) {
2605 GTEST_SKIP();
2606 }
Alec Mouri4049b532021-10-15 20:59:33 -07002607
Alec Mouri5a493722022-01-26 16:43:02 -08002608 initializeRenderEngine();
Alec Mouri4049b532021-10-15 20:59:33 -07002609
Alec Mouri5a493722022-01-26 16:43:02 -08002610 tonemap(
2611 static_cast<ui::Dataspace>(HAL_DATASPACE_STANDARD_BT2020 | HAL_DATASPACE_TRANSFER_HLG |
2612 HAL_DATASPACE_RANGE_FULL),
2613 [](vec3 color) { return EOTF_HLG(color); },
2614 [](vec3 color, float currentLuminaceNits) {
2615 static constexpr float kMaxHLGLuminance = 1000.f;
2616 static const float kHLGGamma = 1.2 + 0.42 * std::log10(currentLuminaceNits / 1000);
2617 return color * kMaxHLGLuminance * std::pow(color.y, kHLGGamma - 1);
2618 });
Alec Mouri4049b532021-10-15 20:59:33 -07002619}
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -05002620
2621TEST_P(RenderEngineTest, r8_behaves_as_mask) {
2622 if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) {
2623 return;
2624 }
2625
2626 initializeRenderEngine();
2627
2628 const auto r8Buffer = allocateR8Buffer(2, 1);
2629 if (!r8Buffer) {
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05002630 GTEST_SKIP() << "Test is only necessary on devices that support r8";
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -05002631 return;
2632 }
2633 {
2634 uint8_t* pixels;
2635 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2636 reinterpret_cast<void**>(&pixels));
2637 // This will be drawn on top of a green buffer. We'll verify that 255
2638 // results in keeping the original green and 0 results in black.
2639 pixels[0] = 0;
2640 pixels[1] = 255;
2641 r8Buffer->getBuffer()->unlock();
2642 }
2643
2644 const auto rect = Rect(0, 0, 2, 1);
2645 const renderengine::DisplaySettings display{
2646 .physicalDisplay = rect,
2647 .clip = rect,
2648 .outputDataspace = ui::Dataspace::SRGB,
2649 };
2650
2651 const auto greenBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(0, 255, 0, 255));
2652 const renderengine::LayerSettings greenLayer{
2653 .geometry.boundaries = rect.toFloatRect(),
2654 .source =
2655 renderengine::PixelSource{
2656 .buffer =
2657 renderengine::Buffer{
2658 .buffer = greenBuffer,
2659 },
2660 },
2661 .alpha = 1.0f,
2662 };
2663 const renderengine::LayerSettings r8Layer{
2664 .geometry.boundaries = rect.toFloatRect(),
2665 .source =
2666 renderengine::PixelSource{
2667 .buffer =
2668 renderengine::Buffer{
2669 .buffer = r8Buffer,
2670 },
2671 },
2672 .alpha = 1.0f,
2673 };
2674
2675 std::vector<renderengine::LayerSettings> layers{greenLayer, r8Layer};
2676 invokeDraw(display, layers);
2677
2678 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 255);
2679 expectBufferColor(Rect(1, 0, 2, 1), 0, 255, 0, 255);
2680}
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05002681
2682TEST_P(RenderEngineTest, r8_respects_color_transform) {
2683 if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) {
2684 return;
2685 }
2686
2687 initializeRenderEngine();
2688
2689 const auto r8Buffer = allocateR8Buffer(2, 1);
2690 if (!r8Buffer) {
2691 GTEST_SKIP() << "Test is only necessary on devices that support r8";
2692 return;
2693 }
2694 {
2695 uint8_t* pixels;
2696 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2697 reinterpret_cast<void**>(&pixels));
2698 pixels[0] = 0;
2699 pixels[1] = 255;
2700 r8Buffer->getBuffer()->unlock();
2701 }
2702
2703 const auto rect = Rect(0, 0, 2, 1);
2704 const renderengine::DisplaySettings display{
2705 .physicalDisplay = rect,
2706 .clip = rect,
2707 .outputDataspace = ui::Dataspace::SRGB,
2708 // Verify that the R8 layer respects the color transform when
2709 // deviceHandlesColorTransform is false. This transform converts
2710 // pure red to pure green. That will occur when the R8 buffer is
2711 // 255. When the R8 buffer is 0, it will still change to black, as
2712 // with r8_behaves_as_mask.
2713 .colorTransform = mat4(0, 1, 0, 0,
2714 0, 0, 0, 0,
2715 0, 0, 1, 0,
2716 0, 0, 0, 1),
2717 .deviceHandlesColorTransform = false,
2718 };
2719
2720 const auto redBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(255, 0, 0, 255));
2721 const renderengine::LayerSettings redLayer{
2722 .geometry.boundaries = rect.toFloatRect(),
2723 .source =
2724 renderengine::PixelSource{
2725 .buffer =
2726 renderengine::Buffer{
2727 .buffer = redBuffer,
2728 },
2729 },
2730 .alpha = 1.0f,
2731 };
2732 const renderengine::LayerSettings r8Layer{
2733 .geometry.boundaries = rect.toFloatRect(),
2734 .source =
2735 renderengine::PixelSource{
2736 .buffer =
2737 renderengine::Buffer{
2738 .buffer = r8Buffer,
2739 },
2740 },
2741 .alpha = 1.0f,
2742 };
2743
2744 std::vector<renderengine::LayerSettings> layers{redLayer, r8Layer};
2745 invokeDraw(display, layers);
2746
2747 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 255);
2748 expectBufferColor(Rect(1, 0, 2, 1), 0, 255, 0, 255);
2749}
2750
2751TEST_P(RenderEngineTest, r8_respects_color_transform_when_device_handles) {
2752 if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) {
2753 return;
2754 }
2755
2756 initializeRenderEngine();
2757
2758 const auto r8Buffer = allocateR8Buffer(2, 1);
2759 if (!r8Buffer) {
2760 GTEST_SKIP() << "Test is only necessary on devices that support r8";
2761 return;
2762 }
2763 {
2764 uint8_t* pixels;
2765 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2766 reinterpret_cast<void**>(&pixels));
2767 pixels[0] = 0;
2768 pixels[1] = 255;
2769 r8Buffer->getBuffer()->unlock();
2770 }
2771
2772 const auto rect = Rect(0, 0, 2, 1);
2773 const renderengine::DisplaySettings display{
2774 .physicalDisplay = rect,
2775 .clip = rect,
2776 .outputDataspace = ui::Dataspace::SRGB,
2777 // If deviceHandlesColorTransform is true, pixels where the A8
2778 // buffer is opaque are unaffected. If the colorTransform is
2779 // invertible, pixels where the A8 buffer are transparent have the
2780 // inverse applied to them so that the DPU will convert them back to
2781 // black. Test with an arbitrary, invertible matrix.
2782 .colorTransform = mat4(1, 0, 0, 2,
2783 3, 1, 2, 5,
2784 0, 5, 3, 0,
2785 0, 1, 0, 2),
2786 .deviceHandlesColorTransform = true,
2787 };
2788
2789 const auto redBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(255, 0, 0, 255));
2790 const renderengine::LayerSettings redLayer{
2791 .geometry.boundaries = rect.toFloatRect(),
2792 .source =
2793 renderengine::PixelSource{
2794 .buffer =
2795 renderengine::Buffer{
2796 .buffer = redBuffer,
2797 },
2798 },
2799 .alpha = 1.0f,
2800 };
2801 const renderengine::LayerSettings r8Layer{
2802 .geometry.boundaries = rect.toFloatRect(),
2803 .source =
2804 renderengine::PixelSource{
2805 .buffer =
2806 renderengine::Buffer{
2807 .buffer = r8Buffer,
2808 },
2809 },
2810 .alpha = 1.0f,
2811 };
2812
2813 std::vector<renderengine::LayerSettings> layers{redLayer, r8Layer};
2814 invokeDraw(display, layers);
2815
2816 expectBufferColor(Rect(1, 0, 2, 1), 255, 0, 0, 255); // Still red.
2817 expectBufferColor(Rect(0, 0, 1, 1), 0, 70, 0, 255);
2818}
Derek Sollenbergerd3f60652021-06-11 15:34:36 -04002819} // namespace renderengine
Alec Mouri6e57f682018-09-29 20:45:08 -07002820} // namespace android
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08002821
2822// TODO(b/129481165): remove the #pragma below and fix conversion issues
Marin Shalamanovbed7fd32020-12-21 20:02:20 +01002823#pragma clang diagnostic pop // ignored "-Wconversion -Wextra"