1 /*
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
17 #undef LOG_TAG
18 #define LOG_TAG "RenderEngineTest"
19
20 // TODO(b/129481165): remove the #pragma below and fix conversion issues
21 #pragma clang diagnostic push
22 #pragma clang diagnostic ignored "-Wconversion"
23 #pragma clang diagnostic ignored "-Wextra"
24
25 #include <com_android_graphics_surfaceflinger_flags.h>
26 #include <cutils/properties.h>
27 #include <gtest/gtest.h>
28 #include <renderengine/ExternalTexture.h>
29 #include <renderengine/RenderEngine.h>
30 #include <renderengine/impl/ExternalTexture.h>
31 #include <sync/sync.h>
32 #include <system/graphics-base-v1.0.h>
33 #include <tonemap/tonemap.h>
34 #include <ui/ColorSpace.h>
35 #include <ui/PixelFormat.h>
36
37 #include <algorithm>
38 #include <chrono>
39 #include <condition_variable>
40 #include <filesystem>
41 #include <fstream>
42 #include <system_error>
43
44 #include "../skia/SkiaGLRenderEngine.h"
45 #include "../skia/SkiaVkRenderEngine.h"
46 #include "../threaded/RenderEngineThreaded.h"
47
48 // TODO: b/341728634 - Clean up conditional compilation.
49 #if COM_ANDROID_GRAPHICS_SURFACEFLINGER_FLAGS(GRAPHITE_RENDERENGINE) || \
50 COM_ANDROID_GRAPHICS_SURFACEFLINGER_FLAGS(FORCE_COMPILE_GRAPHITE_RENDERENGINE)
51 #define COMPILE_GRAPHITE_RENDERENGINE 1
52 #else
53 #define COMPILE_GRAPHITE_RENDERENGINE 0
54 #endif
55
56 constexpr int DEFAULT_DISPLAY_WIDTH = 128;
57 constexpr int DEFAULT_DISPLAY_HEIGHT = 256;
58 constexpr int DEFAULT_DISPLAY_OFFSET = 64;
59 constexpr bool WRITE_BUFFER_TO_FILE_ON_FAILURE = false;
60
61 namespace android {
62 namespace renderengine {
63
64 namespace {
65
EOTF_PQ(double channel)66 double EOTF_PQ(double channel) {
67 float m1 = (2610.0 / 4096.0) / 4.0;
68 float m2 = (2523.0 / 4096.0) * 128.0;
69 float c1 = (3424.0 / 4096.0);
70 float c2 = (2413.0 / 4096.0) * 32.0;
71 float c3 = (2392.0 / 4096.0) * 32.0;
72
73 float tmp = std::pow(std::clamp(channel, 0.0, 1.0), 1.0 / m2);
74 tmp = std::fmax(tmp - c1, 0.0) / (c2 - c3 * tmp);
75 return std::pow(tmp, 1.0 / m1);
76 }
77
EOTF_PQ(vec3 color)78 vec3 EOTF_PQ(vec3 color) {
79 return vec3(EOTF_PQ(color.r), EOTF_PQ(color.g), EOTF_PQ(color.b));
80 }
81
EOTF_HLG(double channel)82 double EOTF_HLG(double channel) {
83 const float a = 0.17883277;
84 const float b = 0.28466892;
85 const float c = 0.55991073;
86 return channel <= 0.5 ? channel * channel / 3.0 : (exp((channel - c) / a) + b) / 12.0;
87 }
88
EOTF_HLG(vec3 color)89 vec3 EOTF_HLG(vec3 color) {
90 return vec3(EOTF_HLG(color.r), EOTF_HLG(color.g), EOTF_HLG(color.b));
91 }
92
OETF_sRGB(double channel)93 double OETF_sRGB(double channel) {
94 return channel <= 0.0031308 ? channel * 12.92 : (pow(channel, 1.0 / 2.4) * 1.055) - 0.055;
95 }
96
sign(float in)97 int sign(float in) {
98 return in >= 0.0 ? 1 : -1;
99 }
100
OETF_sRGB(vec3 linear)101 vec3 OETF_sRGB(vec3 linear) {
102 return vec3(sign(linear.r) * OETF_sRGB(linear.r), sign(linear.g) * OETF_sRGB(linear.g),
103 sign(linear.b) * OETF_sRGB(linear.b));
104 }
105
106 // clang-format off
107 // Converts red channels to green channels, and zeroes out an existing green channel.
108 static const auto kRemoveGreenAndMoveRedToGreenMat4 = mat4(0, 1, 0, 0,
109 0, 0, 0, 0,
110 0, 0, 1, 0,
111 0, 0, 0, 1);
112 // clang-format on
113
114 } // namespace
115
116 class RenderEngineFactory {
117 public:
118 virtual ~RenderEngineFactory() = default;
119
120 virtual std::string name() = 0;
121 virtual renderengine::RenderEngine::GraphicsApi graphicsApi() = 0;
122 virtual renderengine::RenderEngine::SkiaBackend skiaBackend() = 0;
apiSupported()123 bool apiSupported() { return renderengine::RenderEngine::canSupport(graphicsApi()); }
createRenderEngine()124 std::unique_ptr<renderengine::RenderEngine> createRenderEngine() {
125 renderengine::RenderEngineCreationArgs reCreationArgs =
126 renderengine::RenderEngineCreationArgs::Builder()
127 .setPixelFormat(static_cast<int>(ui::PixelFormat::RGBA_8888))
128 .setImageCacheSize(1)
129 .setEnableProtectedContext(false)
130 .setPrecacheToneMapperShaderOnly(false)
131 .setBlurAlgorithm(renderengine::RenderEngine::BlurAlgorithm::KAWASE)
132 .setContextPriority(renderengine::RenderEngine::ContextPriority::MEDIUM)
133 .setThreaded(renderengine::RenderEngine::Threaded::NO)
134 .setGraphicsApi(graphicsApi())
135 .setSkiaBackend(skiaBackend())
136 .build();
137 return renderengine::RenderEngine::create(reCreationArgs);
138 }
139 };
140
141 class SkiaGLESRenderEngineFactory : public RenderEngineFactory {
142 public:
name()143 std::string name() override { return "SkiaGLRenderEngineFactory"; }
144
graphicsApi()145 renderengine::RenderEngine::GraphicsApi graphicsApi() {
146 return renderengine::RenderEngine::GraphicsApi::GL;
147 }
148
skiaBackend()149 renderengine::RenderEngine::SkiaBackend skiaBackend() override {
150 return renderengine::RenderEngine::SkiaBackend::GANESH;
151 }
152 };
153
154 class GaneshVkRenderEngineFactory : public RenderEngineFactory {
155 public:
name()156 std::string name() override { return "GaneshVkRenderEngineFactory"; }
157
graphicsApi()158 renderengine::RenderEngine::GraphicsApi graphicsApi() override {
159 return renderengine::RenderEngine::GraphicsApi::VK;
160 }
161
skiaBackend()162 renderengine::RenderEngine::SkiaBackend skiaBackend() override {
163 return renderengine::RenderEngine::SkiaBackend::GANESH;
164 }
165 };
166
167 // TODO: b/341728634 - Clean up conditional compilation.
168 #if COMPILE_GRAPHITE_RENDERENGINE
169 class GraphiteVkRenderEngineFactory : public RenderEngineFactory {
170 public:
name()171 std::string name() override { return "GraphiteVkRenderEngineFactory"; }
172
graphicsApi()173 renderengine::RenderEngine::GraphicsApi graphicsApi() override {
174 return renderengine::RenderEngine::GraphicsApi::VK;
175 }
176
skiaBackend()177 renderengine::RenderEngine::SkiaBackend skiaBackend() override {
178 return renderengine::RenderEngine::SkiaBackend::GRAPHITE;
179 }
180 };
181 #endif
182
183 class RenderEngineTest : public ::testing::TestWithParam<std::shared_ptr<RenderEngineFactory>> {
184 public:
allocateDefaultBuffer()185 std::shared_ptr<renderengine::ExternalTexture> allocateDefaultBuffer() {
186 return std::make_shared<
187 renderengine::impl::
188 ExternalTexture>(sp<GraphicBuffer>::
189 make(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT,
190 HAL_PIXEL_FORMAT_RGBA_8888, 1,
191 GRALLOC_USAGE_SW_READ_OFTEN |
192 GRALLOC_USAGE_SW_WRITE_OFTEN |
193 GRALLOC_USAGE_HW_RENDER |
194 GRALLOC_USAGE_HW_TEXTURE,
195 "output"),
196 *mRE,
197 renderengine::impl::ExternalTexture::Usage::READABLE |
198 renderengine::impl::ExternalTexture::Usage::
199 WRITEABLE);
200 }
201
202 // Allocates a 1x1 buffer to fill with a solid color
allocateSourceBuffer(uint32_t width,uint32_t height)203 std::shared_ptr<renderengine::ExternalTexture> allocateSourceBuffer(uint32_t width,
204 uint32_t height) {
205 return std::make_shared<
206 renderengine::impl::
207 ExternalTexture>(sp<GraphicBuffer>::
208 make(width, height, HAL_PIXEL_FORMAT_RGBA_8888, 1,
209 GRALLOC_USAGE_SW_READ_OFTEN |
210 GRALLOC_USAGE_SW_WRITE_OFTEN |
211 GRALLOC_USAGE_HW_TEXTURE,
212 "input"),
213 *mRE,
214 renderengine::impl::ExternalTexture::Usage::READABLE |
215 renderengine::impl::ExternalTexture::Usage::
216 WRITEABLE);
217 }
218
allocateAndFillSourceBuffer(uint32_t width,uint32_t height,ubyte4 color)219 std::shared_ptr<renderengine::ExternalTexture> allocateAndFillSourceBuffer(uint32_t width,
220 uint32_t height,
221 ubyte4 color) {
222 const auto buffer = allocateSourceBuffer(width, height);
223 uint8_t* pixels;
224 buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
225 reinterpret_cast<void**>(&pixels));
226 for (uint32_t j = 0; j < height; j++) {
227 uint8_t* dst = pixels + (buffer->getBuffer()->getStride() * j * 4);
228 for (uint32_t i = 0; i < width; i++) {
229 dst[0] = color.r;
230 dst[1] = color.g;
231 dst[2] = color.b;
232 dst[3] = color.a;
233 dst += 4;
234 }
235 }
236 buffer->getBuffer()->unlock();
237 return buffer;
238 }
239
allocateR8Buffer(int width,int height)240 std::shared_ptr<renderengine::ExternalTexture> allocateR8Buffer(int width, int height) {
241 const auto kUsageFlags =
242 static_cast<uint64_t>(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
243 GRALLOC_USAGE_HW_TEXTURE);
244 auto buffer =
245 sp<GraphicBuffer>::make(static_cast<uint32_t>(width), static_cast<uint32_t>(height),
246 android::PIXEL_FORMAT_R_8, 1u, kUsageFlags, "r8");
247 if (buffer->initCheck() != 0) {
248 // Devices are not required to support R8.
249 return nullptr;
250 }
251 return std::make_shared<
252 renderengine::impl::ExternalTexture>(std::move(buffer), *mRE,
253 renderengine::impl::ExternalTexture::Usage::
254 READABLE);
255 }
256
RenderEngineTest()257 RenderEngineTest() {
258 const ::testing::TestInfo* const test_info =
259 ::testing::UnitTest::GetInstance()->current_test_info();
260 ALOGI("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
261 }
262
~RenderEngineTest()263 ~RenderEngineTest() {
264 if (WRITE_BUFFER_TO_FILE_ON_FAILURE && ::testing::Test::HasFailure()) {
265 writeBufferToFile("/data/local/tmp/RenderEngineTest/");
266 }
267 const ::testing::TestInfo* const test_info =
268 ::testing::UnitTest::GetInstance()->current_test_info();
269 ALOGI("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
270 }
271
272 // If called during e.g.
273 // `PerRenderEngineType/RenderEngineTest#drawLayers_fillBufferCheckersRotate90_colorSource/0`
274 // with a directory of `/data/local/tmp/RenderEngineTest`, then mBuffer will be dumped to
275 // `/data/local/tmp/RenderEngineTest/drawLayers_fillBufferCheckersRotate90_colorSource-0.ppm`
276 //
277 // Note: if `directory` does not exist, then its full path will be recursively created with 777
278 // permissions. If `directory` already exists but does not grant the executing user write
279 // permissions, then saving the buffer will fail.
280 //
281 // Since this is test-only code, no security considerations are made.
writeBufferToFile(const filesystem::path & directory)282 void writeBufferToFile(const filesystem::path& directory) {
283 const auto currentTestInfo = ::testing::UnitTest::GetInstance()->current_test_info();
284 LOG_ALWAYS_FATAL_IF(!currentTestInfo,
285 "writeBufferToFile must be called during execution of a test");
286
287 std::string fileName(currentTestInfo->name());
288 // Test names may include the RenderEngine variant separated by '/', which would separate
289 // the file name into a subdirectory if not corrected.
290 std::replace(fileName.begin(), fileName.end(), '/', '-');
291 fileName.append(".ppm");
292
293 std::error_code err;
294 filesystem::create_directories(directory, err);
295 if (err.value()) {
296 ALOGE("Unable to create directory %s for writing %s (%d: %s)", directory.c_str(),
297 fileName.c_str(), err.value(), err.message().c_str());
298 return;
299 }
300
301 // Append operator ("/") ensures exactly one "/" directly before the argument.
302 const filesystem::path filePath = directory / fileName;
303 std::ofstream file(filePath.c_str(), std::ios::binary);
304 if (!file.is_open()) {
305 ALOGE("Unable to open file: %s", filePath.c_str());
306 ALOGE("You may need to do: \"adb shell setenforce 0\" to enable surfaceflinger to "
307 "write debug images, or the %s directory might not give the executing user write "
308 "permission",
309 directory.c_str());
310 return;
311 }
312
313 uint8_t* pixels;
314 mBuffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
315 reinterpret_cast<void**>(&pixels));
316
317 file << "P6\n";
318 file << mBuffer->getBuffer()->getWidth() << "\n";
319 file << mBuffer->getBuffer()->getHeight() << "\n";
320 file << 255 << "\n";
321
322 std::vector<uint8_t> outBuffer(mBuffer->getBuffer()->getWidth() *
323 mBuffer->getBuffer()->getHeight() * 3);
324 auto outPtr = reinterpret_cast<uint8_t*>(outBuffer.data());
325
326 for (int32_t j = 0; j < mBuffer->getBuffer()->getHeight(); j++) {
327 const uint8_t* src = pixels + (mBuffer->getBuffer()->getStride() * j) * 4;
328 for (int32_t i = 0; i < mBuffer->getBuffer()->getWidth(); i++) {
329 // Only copy R, G and B components
330 outPtr[0] = src[0];
331 outPtr[1] = src[1];
332 outPtr[2] = src[2];
333 outPtr += 3;
334
335 src += 4;
336 }
337 }
338 file.write(reinterpret_cast<char*>(outBuffer.data()), outBuffer.size());
339 ALOGI("Image of incorrect output written to %s", filePath.c_str());
340 mBuffer->getBuffer()->unlock();
341 }
342
expectBufferColor(const Region & region,uint8_t r,uint8_t g,uint8_t b,uint8_t a)343 void expectBufferColor(const Region& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
344 size_t c;
345 Rect const* rect = region.getArray(&c);
346 for (size_t i = 0; i < c; i++, rect++) {
347 expectBufferColor(*rect, r, g, b, a);
348 }
349 }
350
expectBufferColor(const Point & point,uint8_t r,uint8_t g,uint8_t b,uint8_t a,uint8_t tolerance=0)351 void expectBufferColor(const Point& point, uint8_t r, uint8_t g, uint8_t b, uint8_t a,
352 uint8_t tolerance = 0) {
353 expectBufferColor(Rect(point.x, point.y, point.x + 1, point.y + 1), r, g, b, a, tolerance);
354 }
355
expectBufferColor(const Rect & rect,uint8_t r,uint8_t g,uint8_t b,uint8_t a,uint8_t tolerance=0)356 void expectBufferColor(const Rect& rect, uint8_t r, uint8_t g, uint8_t b, uint8_t a,
357 uint8_t tolerance = 0) {
358 auto generator = [=](Point) { return ubyte4(r, g, b, a); };
359 expectBufferColor(rect, generator, tolerance);
360 }
361
362 using ColorGenerator = std::function<ubyte4(Point location)>;
363
expectBufferColor(const Rect & rect,ColorGenerator generator,uint8_t tolerance=0)364 void expectBufferColor(const Rect& rect, ColorGenerator generator, uint8_t tolerance = 0) {
365 auto colorCompare = [tolerance](const uint8_t* colorA, const uint8_t* colorB) {
366 auto colorBitCompare = [tolerance](uint8_t a, uint8_t b) {
367 uint8_t tmp = a >= b ? a - b : b - a;
368 return tmp <= tolerance;
369 };
370 return std::equal(colorA, colorA + 4, colorB, colorBitCompare);
371 };
372
373 expectBufferColor(rect, generator, colorCompare);
374 }
375
expectBufferColor(const Rect & region,ColorGenerator generator,std::function<bool (const uint8_t * a,const uint8_t * b)> colorCompare)376 void expectBufferColor(const Rect& region, ColorGenerator generator,
377 std::function<bool(const uint8_t* a, const uint8_t* b)> colorCompare) {
378 uint8_t* pixels;
379 mBuffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
380 reinterpret_cast<void**>(&pixels));
381 int32_t maxFails = 10;
382 int32_t fails = 0;
383 for (int32_t j = 0; j < region.getHeight(); j++) {
384 const uint8_t* src = pixels +
385 (mBuffer->getBuffer()->getStride() * (region.top + j) + region.left) * 4;
386 for (int32_t i = 0; i < region.getWidth(); i++) {
387 const auto location = Point(region.left + i, region.top + j);
388 const ubyte4 colors = generator(location);
389 const uint8_t expected[4] = {colors.r, colors.g, colors.b, colors.a};
390 bool colorMatches = colorCompare(src, expected);
391 EXPECT_TRUE(colorMatches)
392 << GetParam()->name().c_str() << ": "
393 << "pixel @ (" << location.x << ", " << location.y << "): "
394 << "expected (" << static_cast<uint32_t>(colors.r) << ", "
395 << static_cast<uint32_t>(colors.g) << ", "
396 << static_cast<uint32_t>(colors.b) << ", "
397 << static_cast<uint32_t>(colors.a) << "), "
398 << "got (" << static_cast<uint32_t>(src[0]) << ", "
399 << static_cast<uint32_t>(src[1]) << ", " << static_cast<uint32_t>(src[2])
400 << ", " << static_cast<uint32_t>(src[3]) << ")";
401 src += 4;
402 if (!colorMatches && ++fails >= maxFails) {
403 break;
404 }
405 }
406 if (fails >= maxFails) {
407 break;
408 }
409 }
410 mBuffer->getBuffer()->unlock();
411 }
412
expectAlpha(const Rect & rect,uint8_t a)413 void expectAlpha(const Rect& rect, uint8_t a) {
414 auto generator = [=](Point) { return ubyte4(0, 0, 0, a); };
415 auto colorCompare = [](const uint8_t* colorA, const uint8_t* colorB) {
416 return colorA[3] == colorB[3];
417 };
418 expectBufferColor(rect, generator, colorCompare);
419 }
420
expectShadowColor(const renderengine::LayerSettings & castingLayer,const ShadowSettings & shadow,const ubyte4 & casterColor,const ubyte4 & backgroundColor)421 void expectShadowColor(const renderengine::LayerSettings& castingLayer,
422 const ShadowSettings& shadow, const ubyte4& casterColor,
423 const ubyte4& backgroundColor) {
424 const Rect casterRect(castingLayer.geometry.boundaries);
425 Region casterRegion = Region(casterRect);
426 const float casterCornerRadius = (castingLayer.geometry.roundedCornersRadius.x +
427 castingLayer.geometry.roundedCornersRadius.y) /
428 2.0;
429 if (casterCornerRadius > 0.0f) {
430 // ignore the corners if a corner radius is set
431 Rect cornerRect(casterCornerRadius, casterCornerRadius);
432 casterRegion.subtractSelf(cornerRect.offsetTo(casterRect.left, casterRect.top));
433 casterRegion.subtractSelf(
434 cornerRect.offsetTo(casterRect.right - casterCornerRadius, casterRect.top));
435 casterRegion.subtractSelf(
436 cornerRect.offsetTo(casterRect.left, casterRect.bottom - casterCornerRadius));
437 casterRegion.subtractSelf(cornerRect.offsetTo(casterRect.right - casterCornerRadius,
438 casterRect.bottom - casterCornerRadius));
439 }
440
441 const float shadowInset = shadow.length * -1.0f;
442 const Rect casterWithShadow =
443 Rect(casterRect).inset(shadowInset, shadowInset, shadowInset, shadowInset);
444 const Region shadowRegion = Region(casterWithShadow).subtractSelf(casterRect);
445 const Region backgroundRegion = Region(fullscreenRect()).subtractSelf(casterWithShadow);
446
447 // verify casting layer
448 expectBufferColor(casterRegion, casterColor.r, casterColor.g, casterColor.b, casterColor.a);
449
450 // verify shadows by testing just the alpha since its difficult to validate the shadow color
451 size_t c;
452 Rect const* r = shadowRegion.getArray(&c);
453 for (size_t i = 0; i < c; i++, r++) {
454 expectAlpha(*r, 255);
455 }
456
457 // verify background
458 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
459 backgroundColor.a);
460 }
461
expectShadowColorWithoutCaster(const FloatRect & casterBounds,const ShadowSettings & shadow,const ubyte4 & backgroundColor)462 void expectShadowColorWithoutCaster(const FloatRect& casterBounds, const ShadowSettings& shadow,
463 const ubyte4& backgroundColor) {
464 const float shadowInset = shadow.length * -1.0f;
465 const Rect casterRect(casterBounds);
466 const Rect shadowRect =
467 Rect(casterRect).inset(shadowInset, shadowInset, shadowInset, shadowInset);
468
469 const Region backgroundRegion =
470 Region(fullscreenRect()).subtractSelf(casterRect).subtractSelf(shadowRect);
471
472 expectAlpha(shadowRect, 255);
473 // (0, 0, 0) fill on the bounds of the layer should be ignored.
474 expectBufferColor(casterRect, 255, 255, 255, 255, 254);
475
476 // verify background
477 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
478 backgroundColor.a);
479 }
480
getShadowSettings(const vec2 & casterPos,float shadowLength,bool casterIsTranslucent)481 static ShadowSettings getShadowSettings(const vec2& casterPos, float shadowLength,
482 bool casterIsTranslucent) {
483 ShadowSettings shadow;
484 shadow.ambientColor = {0.0f, 0.0f, 0.0f, 0.039f};
485 shadow.spotColor = {0.0f, 0.0f, 0.0f, 0.19f};
486 shadow.lightPos = vec3(casterPos.x, casterPos.y, 0);
487 shadow.lightRadius = 0.0f;
488 shadow.length = shadowLength;
489 shadow.casterIsTranslucent = casterIsTranslucent;
490 return shadow;
491 }
492
fullscreenRect()493 static Rect fullscreenRect() { return Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT); }
494
offsetRect()495 static Rect offsetRect() {
496 return Rect(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_WIDTH,
497 DEFAULT_DISPLAY_HEIGHT);
498 }
499
offsetRectAtZero()500 static Rect offsetRectAtZero() {
501 return Rect(DEFAULT_DISPLAY_WIDTH - DEFAULT_DISPLAY_OFFSET,
502 DEFAULT_DISPLAY_HEIGHT - DEFAULT_DISPLAY_OFFSET);
503 }
504
invokeDraw(const renderengine::DisplaySettings & settings,const std::vector<renderengine::LayerSettings> & layers)505 void invokeDraw(const renderengine::DisplaySettings& settings,
506 const std::vector<renderengine::LayerSettings>& layers) {
507 ftl::Future<FenceResult> future =
508 mRE->drawLayers(settings, layers, mBuffer, base::unique_fd());
509 ASSERT_TRUE(future.valid());
510
511 auto result = future.get();
512 ASSERT_TRUE(result.ok());
513
514 auto fence = result.value();
515 fence->waitForever(LOG_TAG);
516 }
517
drawEmptyLayers()518 void drawEmptyLayers() {
519 renderengine::DisplaySettings settings;
520 std::vector<renderengine::LayerSettings> layers;
521 invokeDraw(settings, layers);
522 }
523
524 template <typename SourceVariant>
525 void fillBuffer(half r, half g, half b, half a);
526
527 template <typename SourceVariant>
528 void fillRedBuffer();
529
530 template <typename SourceVariant>
531 void fillGreenBuffer();
532
533 template <typename SourceVariant>
534 void fillBlueBuffer();
535
536 template <typename SourceVariant>
537 void fillRedTransparentBuffer();
538
539 template <typename SourceVariant>
540 void fillRedOffsetBuffer();
541
542 template <typename SourceVariant>
543 void fillBufferPhysicalOffset();
544
545 template <typename SourceVariant>
546 void fillBufferCheckers(uint32_t rotation);
547
548 template <typename SourceVariant>
549 void fillBufferCheckersRotate0();
550
551 template <typename SourceVariant>
552 void fillBufferCheckersRotate90();
553
554 template <typename SourceVariant>
555 void fillBufferCheckersRotate180();
556
557 template <typename SourceVariant>
558 void fillBufferCheckersRotate270();
559
560 template <typename SourceVariant>
561 void fillBufferWithLayerTransform();
562
563 template <typename SourceVariant>
564 void fillBufferLayerTransform();
565
566 template <typename SourceVariant>
567 void fillBufferWithColorTransform();
568
569 template <typename SourceVariant>
570 void fillBufferColorTransform();
571
572 template <typename SourceVariant>
573 void fillBufferWithColorTransformAndSourceDataspace(const ui::Dataspace sourceDataspace);
574
575 template <typename SourceVariant>
576 void fillBufferColorTransformAndSourceDataspace();
577
578 template <typename SourceVariant>
579 void fillBufferWithColorTransformAndOutputDataspace(const ui::Dataspace outputDataspace);
580
581 template <typename SourceVariant>
582 void fillBufferColorTransformAndOutputDataspace();
583
584 template <typename SourceVariant>
585 void fillBufferWithColorTransformZeroLayerAlpha();
586
587 template <typename SourceVariant>
588 void fillBufferColorTransformZeroLayerAlpha();
589
590 template <typename SourceVariant>
591 void fillRedBufferWithRoundedCorners();
592
593 template <typename SourceVariant>
594 void fillBufferWithRoundedCorners();
595
596 template <typename SourceVariant>
597 void fillBufferAndBlurBackground();
598
599 template <typename SourceVariant>
600 void fillSmallLayerAndBlurBackground();
601
602 template <typename SourceVariant>
603 void overlayCorners();
604
605 void fillRedBufferTextureTransform();
606
607 void fillBufferTextureTransform();
608
609 void fillRedBufferWithPremultiplyAlpha();
610
611 void fillBufferWithPremultiplyAlpha();
612
613 void fillRedBufferWithoutPremultiplyAlpha();
614
615 void fillBufferWithoutPremultiplyAlpha();
616
617 void fillGreenColorBufferThenClearRegion();
618
619 template <typename SourceVariant>
620 void drawShadow(const renderengine::LayerSettings& castingLayer, const ShadowSettings& shadow,
621 const ubyte4& casterColor, const ubyte4& backgroundColor);
622
623 void drawShadowWithoutCaster(const FloatRect& castingBounds, const ShadowSettings& shadow,
624 const ubyte4& backgroundColor);
625
626 // Tonemaps grey values from sourceDataspace -> Display P3 and checks that GPU and CPU
627 // implementations are identical Also implicitly checks that the injected tonemap shader
628 // compiles
629 void tonemap(ui::Dataspace sourceDataspace, std::function<vec3(vec3)> eotf,
630 std::function<vec3(vec3, float)> scaleOotf);
631
632 void initializeRenderEngine();
633
634 std::unique_ptr<renderengine::RenderEngine> mRE;
635 std::shared_ptr<renderengine::ExternalTexture> mBuffer;
636 };
637
initializeRenderEngine()638 void RenderEngineTest::initializeRenderEngine() {
639 const auto& renderEngineFactory = GetParam();
640 mRE = renderEngineFactory->createRenderEngine();
641 mBuffer = allocateDefaultBuffer();
642 }
643
644 struct ColorSourceVariant {
fillColorandroid::renderengine::ColorSourceVariant645 static void fillColor(renderengine::LayerSettings& layer, half r, half g, half b,
646 RenderEngineTest* /*fixture*/) {
647 layer.source.solidColor = half3(r, g, b);
648 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
649 }
650 };
651
652 struct RelaxOpaqueBufferVariant {
setOpaqueBitandroid::renderengine::RelaxOpaqueBufferVariant653 static void setOpaqueBit(renderengine::LayerSettings& layer) {
654 layer.source.buffer.isOpaque = false;
655 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
656 }
657
getAlphaChannelandroid::renderengine::RelaxOpaqueBufferVariant658 static uint8_t getAlphaChannel() { return 255; }
659 };
660
661 struct ForceOpaqueBufferVariant {
setOpaqueBitandroid::renderengine::ForceOpaqueBufferVariant662 static void setOpaqueBit(renderengine::LayerSettings& layer) {
663 layer.source.buffer.isOpaque = true;
664 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
665 }
666
getAlphaChannelandroid::renderengine::ForceOpaqueBufferVariant667 static uint8_t getAlphaChannel() {
668 // The isOpaque bit will override the alpha channel, so this should be
669 // arbitrary.
670 return 50;
671 }
672 };
673
674 template <typename OpaquenessVariant>
675 struct BufferSourceVariant {
fillColorandroid::renderengine::BufferSourceVariant676 static void fillColor(renderengine::LayerSettings& layer, half r, half g, half b,
677 RenderEngineTest* fixture) {
678 const auto buf = fixture->allocateSourceBuffer(1, 1);
679
680 uint8_t* pixels;
681 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
682 reinterpret_cast<void**>(&pixels));
683
684 for (int32_t j = 0; j < buf->getBuffer()->getHeight(); j++) {
685 uint8_t* iter = pixels + (buf->getBuffer()->getStride() * j) * 4;
686 for (int32_t i = 0; i < buf->getBuffer()->getWidth(); i++) {
687 iter[0] = uint8_t(r * 255);
688 iter[1] = uint8_t(g * 255);
689 iter[2] = uint8_t(b * 255);
690 iter[3] = OpaquenessVariant::getAlphaChannel();
691 iter += 4;
692 }
693 }
694
695 buf->getBuffer()->unlock();
696
697 layer.source.buffer.buffer = buf;
698 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
699 OpaquenessVariant::setOpaqueBit(layer);
700 }
701 };
702
703 template <typename SourceVariant>
fillBuffer(half r,half g,half b,half a)704 void RenderEngineTest::fillBuffer(half r, half g, half b, half a) {
705 renderengine::DisplaySettings settings;
706 settings.physicalDisplay = fullscreenRect();
707 settings.clip = fullscreenRect();
708 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
709
710 std::vector<renderengine::LayerSettings> layers;
711
712 renderengine::LayerSettings layer;
713 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
714 layer.geometry.boundaries = fullscreenRect().toFloatRect();
715 SourceVariant::fillColor(layer, r, g, b, this);
716 layer.alpha = a;
717
718 layers.push_back(layer);
719
720 invokeDraw(settings, layers);
721 }
722
723 template <typename SourceVariant>
fillRedBuffer()724 void RenderEngineTest::fillRedBuffer() {
725 fillBuffer<SourceVariant>(1.0f, 0.0f, 0.0f, 1.0f);
726 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
727 }
728
729 template <typename SourceVariant>
fillGreenBuffer()730 void RenderEngineTest::fillGreenBuffer() {
731 fillBuffer<SourceVariant>(0.0f, 1.0f, 0.0f, 1.0f);
732 expectBufferColor(fullscreenRect(), 0, 255, 0, 255);
733 }
734
735 template <typename SourceVariant>
fillBlueBuffer()736 void RenderEngineTest::fillBlueBuffer() {
737 fillBuffer<SourceVariant>(0.0f, 0.0f, 1.0f, 1.0f);
738 expectBufferColor(fullscreenRect(), 0, 0, 255, 255);
739 }
740
741 template <typename SourceVariant>
fillRedTransparentBuffer()742 void RenderEngineTest::fillRedTransparentBuffer() {
743 fillBuffer<SourceVariant>(1.0f, 0.0f, 0.0f, .2f);
744 expectBufferColor(fullscreenRect(), 51, 0, 0, 51);
745 }
746
747 template <typename SourceVariant>
fillRedOffsetBuffer()748 void RenderEngineTest::fillRedOffsetBuffer() {
749 renderengine::DisplaySettings settings;
750 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
751 settings.physicalDisplay = offsetRect();
752 settings.clip = offsetRectAtZero();
753
754 std::vector<renderengine::LayerSettings> layers;
755
756 renderengine::LayerSettings layer;
757 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
758 layer.geometry.boundaries = offsetRectAtZero().toFloatRect();
759 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
760 layer.alpha = 1.0f;
761
762 layers.push_back(layer);
763 invokeDraw(settings, layers);
764 }
765
766 template <typename SourceVariant>
fillBufferPhysicalOffset()767 void RenderEngineTest::fillBufferPhysicalOffset() {
768 fillRedOffsetBuffer<SourceVariant>();
769
770 expectBufferColor(Rect(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_WIDTH,
771 DEFAULT_DISPLAY_HEIGHT),
772 255, 0, 0, 255);
773 Rect offsetRegionLeft(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_HEIGHT);
774 Rect offsetRegionTop(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_OFFSET);
775
776 expectBufferColor(offsetRegionLeft, 0, 0, 0, 0);
777 expectBufferColor(offsetRegionTop, 0, 0, 0, 0);
778 }
779
780 template <typename SourceVariant>
fillBufferCheckers(uint32_t orientationFlag)781 void RenderEngineTest::fillBufferCheckers(uint32_t orientationFlag) {
782 renderengine::DisplaySettings settings;
783 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
784 settings.physicalDisplay = fullscreenRect();
785 // Here logical space is 2x2
786 settings.clip = Rect(2, 2);
787 settings.orientation = orientationFlag;
788
789 std::vector<renderengine::LayerSettings> layers;
790
791 renderengine::LayerSettings layerOne;
792 layerOne.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
793 Rect rectOne(0, 0, 1, 1);
794 layerOne.geometry.boundaries = rectOne.toFloatRect();
795 SourceVariant::fillColor(layerOne, 1.0f, 0.0f, 0.0f, this);
796 layerOne.alpha = 1.0f;
797
798 renderengine::LayerSettings layerTwo;
799 layerTwo.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
800 Rect rectTwo(0, 1, 1, 2);
801 layerTwo.geometry.boundaries = rectTwo.toFloatRect();
802 SourceVariant::fillColor(layerTwo, 0.0f, 1.0f, 0.0f, this);
803 layerTwo.alpha = 1.0f;
804
805 renderengine::LayerSettings layerThree;
806 layerThree.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
807 Rect rectThree(1, 0, 2, 1);
808 layerThree.geometry.boundaries = rectThree.toFloatRect();
809 SourceVariant::fillColor(layerThree, 0.0f, 0.0f, 1.0f, this);
810 layerThree.alpha = 1.0f;
811
812 layers.push_back(layerOne);
813 layers.push_back(layerTwo);
814 layers.push_back(layerThree);
815
816 invokeDraw(settings, layers);
817 }
818
819 template <typename SourceVariant>
fillBufferCheckersRotate0()820 void RenderEngineTest::fillBufferCheckersRotate0() {
821 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_0);
822 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0,
823 255);
824 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
825 DEFAULT_DISPLAY_HEIGHT / 2),
826 0, 0, 255, 255);
827 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
828 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
829 0, 0, 0, 0);
830 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
831 DEFAULT_DISPLAY_HEIGHT),
832 0, 255, 0, 255);
833 }
834
835 template <typename SourceVariant>
fillBufferCheckersRotate90()836 void RenderEngineTest::fillBufferCheckersRotate90() {
837 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_90);
838 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 255, 0,
839 255);
840 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
841 DEFAULT_DISPLAY_HEIGHT / 2),
842 255, 0, 0, 255);
843 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
844 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
845 0, 0, 255, 255);
846 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
847 DEFAULT_DISPLAY_HEIGHT),
848 0, 0, 0, 0);
849 }
850
851 template <typename SourceVariant>
fillBufferCheckersRotate180()852 void RenderEngineTest::fillBufferCheckersRotate180() {
853 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_180);
854 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 0,
855 0);
856 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
857 DEFAULT_DISPLAY_HEIGHT / 2),
858 0, 255, 0, 255);
859 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
860 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
861 255, 0, 0, 255);
862 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
863 DEFAULT_DISPLAY_HEIGHT),
864 0, 0, 255, 255);
865 }
866
867 template <typename SourceVariant>
fillBufferCheckersRotate270()868 void RenderEngineTest::fillBufferCheckersRotate270() {
869 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_270);
870 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 255,
871 255);
872 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
873 DEFAULT_DISPLAY_HEIGHT / 2),
874 0, 0, 0, 0);
875 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
876 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
877 0, 255, 0, 255);
878 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
879 DEFAULT_DISPLAY_HEIGHT),
880 255, 0, 0, 255);
881 }
882
883 template <typename SourceVariant>
fillBufferWithLayerTransform()884 void RenderEngineTest::fillBufferWithLayerTransform() {
885 renderengine::DisplaySettings settings;
886 settings.physicalDisplay = fullscreenRect();
887 // Here logical space is 2x2
888 settings.clip = Rect(2, 2);
889 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
890
891 std::vector<renderengine::LayerSettings> layers;
892
893 renderengine::LayerSettings layer;
894 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
895 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
896 // Translate one pixel diagonally
897 layer.geometry.positionTransform = mat4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1);
898 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
899 layer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
900 layer.alpha = 1.0f;
901
902 layers.push_back(layer);
903
904 invokeDraw(settings, layers);
905 }
906
907 template <typename SourceVariant>
fillBufferLayerTransform()908 void RenderEngineTest::fillBufferLayerTransform() {
909 fillBufferWithLayerTransform<SourceVariant>();
910 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 0, 0);
911 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
912 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
913 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
914 255, 0, 0, 255);
915 }
916
917 template <typename SourceVariant>
fillBufferWithColorTransform()918 void RenderEngineTest::fillBufferWithColorTransform() {
919 renderengine::DisplaySettings settings;
920 settings.physicalDisplay = fullscreenRect();
921 settings.clip = Rect(1, 1);
922 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
923
924 std::vector<renderengine::LayerSettings> layers;
925
926 renderengine::LayerSettings layer;
927 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
928 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
929 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
930 layer.alpha = 1.0f;
931
932 // construct a fake color matrix
933 // annihilate green and blue channels
934 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
935 // set red channel to red + green
936 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
937
938 layer.alpha = 1.0f;
939 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
940
941 layers.push_back(layer);
942
943 invokeDraw(settings, layers);
944 }
945
946 template <typename SourceVariant>
fillBufferWithColorTransformAndSourceDataspace(const ui::Dataspace sourceDataspace)947 void RenderEngineTest::fillBufferWithColorTransformAndSourceDataspace(
948 const ui::Dataspace sourceDataspace) {
949 renderengine::DisplaySettings settings;
950 settings.physicalDisplay = fullscreenRect();
951 settings.clip = Rect(1, 1);
952 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
953
954 std::vector<renderengine::LayerSettings> layers;
955
956 renderengine::LayerSettings layer;
957 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
958 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
959 layer.sourceDataspace = sourceDataspace;
960 layer.alpha = 1.0f;
961
962 // construct a fake color matrix
963 // annihilate green and blue channels
964 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
965 // set red channel to red + green
966 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
967
968 layer.alpha = 1.0f;
969 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
970
971 layers.push_back(layer);
972
973 invokeDraw(settings, layers);
974 }
975
976 template <typename SourceVariant>
fillBufferColorTransform()977 void RenderEngineTest::fillBufferColorTransform() {
978 fillBufferWithColorTransform<SourceVariant>();
979 expectBufferColor(fullscreenRect(), 172, 0, 0, 255, 1);
980 }
981
982 template <typename SourceVariant>
fillBufferColorTransformAndSourceDataspace()983 void RenderEngineTest::fillBufferColorTransformAndSourceDataspace() {
984 unordered_map<ui::Dataspace, ubyte4> dataspaceToColorMap;
985 dataspaceToColorMap[ui::Dataspace::V0_BT709] = {77, 0, 0, 255};
986 dataspaceToColorMap[ui::Dataspace::BT2020] = {101, 0, 0, 255};
987 dataspaceToColorMap[ui::Dataspace::ADOBE_RGB] = {75, 0, 0, 255};
988 ui::Dataspace customizedDataspace = static_cast<ui::Dataspace>(
989 ui::Dataspace::STANDARD_BT709 | ui::Dataspace::TRANSFER_GAMMA2_2 |
990 ui::Dataspace::RANGE_FULL);
991 dataspaceToColorMap[customizedDataspace] = {61, 0, 0, 255};
992 for (const auto& [sourceDataspace, color] : dataspaceToColorMap) {
993 fillBufferWithColorTransformAndSourceDataspace<SourceVariant>(sourceDataspace);
994 expectBufferColor(fullscreenRect(), color.r, color.g, color.b, color.a, 1);
995 }
996 }
997
998 template <typename SourceVariant>
fillBufferWithColorTransformAndOutputDataspace(const ui::Dataspace outputDataspace)999 void RenderEngineTest::fillBufferWithColorTransformAndOutputDataspace(
1000 const ui::Dataspace outputDataspace) {
1001 renderengine::DisplaySettings settings;
1002 settings.physicalDisplay = fullscreenRect();
1003 settings.clip = Rect(1, 1);
1004 settings.outputDataspace = outputDataspace;
1005
1006 std::vector<renderengine::LayerSettings> layers;
1007
1008 renderengine::LayerSettings layer;
1009 layer.sourceDataspace = ui::Dataspace::V0_SCRGB_LINEAR;
1010 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1011 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
1012 layer.alpha = 1.0f;
1013
1014 // construct a fake color matrix
1015 // annihilate green and blue channels
1016 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
1017 // set red channel to red + green
1018 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
1019
1020 layer.alpha = 1.0f;
1021 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1022
1023 layers.push_back(layer);
1024
1025 invokeDraw(settings, layers);
1026 }
1027
1028 template <typename SourceVariant>
fillBufferColorTransformAndOutputDataspace()1029 void RenderEngineTest::fillBufferColorTransformAndOutputDataspace() {
1030 unordered_map<ui::Dataspace, ubyte4> dataspaceToColorMap;
1031 dataspaceToColorMap[ui::Dataspace::V0_BT709] = {198, 0, 0, 255};
1032 dataspaceToColorMap[ui::Dataspace::BT2020] = {187, 0, 0, 255};
1033 dataspaceToColorMap[ui::Dataspace::ADOBE_RGB] = {192, 0, 0, 255};
1034 ui::Dataspace customizedDataspace = static_cast<ui::Dataspace>(
1035 ui::Dataspace::STANDARD_BT709 | ui::Dataspace::TRANSFER_GAMMA2_6 |
1036 ui::Dataspace::RANGE_FULL);
1037 dataspaceToColorMap[customizedDataspace] = {205, 0, 0, 255};
1038 for (const auto& [outputDataspace, color] : dataspaceToColorMap) {
1039 fillBufferWithColorTransformAndOutputDataspace<SourceVariant>(outputDataspace);
1040 expectBufferColor(fullscreenRect(), color.r, color.g, color.b, color.a, 1);
1041 }
1042 }
1043
1044 template <typename SourceVariant>
fillBufferWithColorTransformZeroLayerAlpha()1045 void RenderEngineTest::fillBufferWithColorTransformZeroLayerAlpha() {
1046 renderengine::DisplaySettings settings;
1047 settings.physicalDisplay = fullscreenRect();
1048 settings.clip = Rect(1, 1);
1049
1050 std::vector<renderengine::LayerSettings> layers;
1051
1052 renderengine::LayerSettings layer;
1053 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1054 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
1055 layer.alpha = 0;
1056
1057 // construct a fake color matrix
1058 // simple inverse color
1059 settings.colorTransform = mat4(-1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 1, 1, 1, 1);
1060
1061 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1062
1063 layers.push_back(layer);
1064
1065 invokeDraw(settings, layers);
1066 }
1067
1068 template <typename SourceVariant>
fillBufferColorTransformZeroLayerAlpha()1069 void RenderEngineTest::fillBufferColorTransformZeroLayerAlpha() {
1070 fillBufferWithColorTransformZeroLayerAlpha<SourceVariant>();
1071 expectBufferColor(fullscreenRect(), 0, 0, 0, 0);
1072 }
1073
1074 template <typename SourceVariant>
fillRedBufferWithRoundedCorners()1075 void RenderEngineTest::fillRedBufferWithRoundedCorners() {
1076 renderengine::DisplaySettings settings;
1077 settings.physicalDisplay = fullscreenRect();
1078 settings.clip = fullscreenRect();
1079 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1080
1081 std::vector<renderengine::LayerSettings> layers;
1082
1083 renderengine::LayerSettings layer;
1084 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1085 layer.geometry.boundaries = fullscreenRect().toFloatRect();
1086 layer.geometry.roundedCornersRadius = {5.0f, 5.0f};
1087 layer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
1088 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
1089 layer.alpha = 1.0f;
1090
1091 layers.push_back(layer);
1092
1093 invokeDraw(settings, layers);
1094 }
1095
1096 template <typename SourceVariant>
fillBufferWithRoundedCorners()1097 void RenderEngineTest::fillBufferWithRoundedCorners() {
1098 fillRedBufferWithRoundedCorners<SourceVariant>();
1099 // Corners should be ignored...
1100 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 0);
1101 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, 0, DEFAULT_DISPLAY_WIDTH, 1), 0, 0, 0, 0);
1102 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT - 1, 1, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
1103 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1,
1104 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1105 0, 0, 0, 0);
1106 // ...And the non-rounded portion should be red.
1107 // Other pixels may be anti-aliased, so let's not check those.
1108 expectBufferColor(Rect(5, 5, DEFAULT_DISPLAY_WIDTH - 5, DEFAULT_DISPLAY_HEIGHT - 5), 255, 0, 0,
1109 255);
1110 }
1111
1112 template <typename SourceVariant>
fillBufferAndBlurBackground()1113 void RenderEngineTest::fillBufferAndBlurBackground() {
1114 auto blurRadius = 50;
1115 auto center = DEFAULT_DISPLAY_WIDTH / 2;
1116
1117 renderengine::DisplaySettings settings;
1118 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1119 settings.physicalDisplay = fullscreenRect();
1120 settings.clip = fullscreenRect();
1121
1122 std::vector<renderengine::LayerSettings> layers;
1123
1124 renderengine::LayerSettings backgroundLayer;
1125 backgroundLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1126 backgroundLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1127 SourceVariant::fillColor(backgroundLayer, 0.0f, 1.0f, 0.0f, this);
1128 backgroundLayer.alpha = 1.0f;
1129 layers.emplace_back(backgroundLayer);
1130
1131 renderengine::LayerSettings leftLayer;
1132 leftLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1133 leftLayer.geometry.boundaries =
1134 Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT).toFloatRect();
1135 SourceVariant::fillColor(leftLayer, 1.0f, 0.0f, 0.0f, this);
1136 leftLayer.alpha = 1.0f;
1137 layers.emplace_back(leftLayer);
1138
1139 renderengine::LayerSettings blurLayer;
1140 blurLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1141 blurLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1142 blurLayer.backgroundBlurRadius = blurRadius;
1143 SourceVariant::fillColor(blurLayer, 0.0f, 0.0f, 1.0f, this);
1144 blurLayer.alpha = 0;
1145 layers.emplace_back(blurLayer);
1146
1147 invokeDraw(settings, layers);
1148
1149 // solid color
1150 expectBufferColor(Rect(0, 0, 1, 1), 255, 0, 0, 255, 0 /* tolerance */);
1151
1152 if (mRE->supportsBackgroundBlur()) {
1153 // blurred color (downsampling should result in the center color being close to 128)
1154 expectBufferColor(Rect(center - 1, center - 5, center + 1, center + 5), 128, 128, 0, 255,
1155 50 /* tolerance */);
1156 }
1157 }
1158
1159 template <typename SourceVariant>
fillSmallLayerAndBlurBackground()1160 void RenderEngineTest::fillSmallLayerAndBlurBackground() {
1161 auto blurRadius = 50;
1162 renderengine::DisplaySettings settings;
1163 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1164 settings.physicalDisplay = fullscreenRect();
1165 settings.clip = fullscreenRect();
1166
1167 std::vector<renderengine::LayerSettings> layers;
1168
1169 renderengine::LayerSettings backgroundLayer;
1170 backgroundLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1171 backgroundLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1172 SourceVariant::fillColor(backgroundLayer, 1.0f, 0.0f, 0.0f, this);
1173 backgroundLayer.alpha = 1.0f;
1174 layers.push_back(backgroundLayer);
1175
1176 renderengine::LayerSettings blurLayer;
1177 blurLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1178 blurLayer.geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f);
1179 blurLayer.backgroundBlurRadius = blurRadius;
1180 SourceVariant::fillColor(blurLayer, 0.0f, 0.0f, 1.0f, this);
1181 blurLayer.alpha = 0;
1182 layers.push_back(blurLayer);
1183
1184 invokeDraw(settings, layers);
1185
1186 // Give a generous tolerance - the blur rectangle is very small and this test is
1187 // mainly concerned with ensuring that there's no device failure.
1188 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT), 255, 0, 0, 255,
1189 40 /* tolerance */);
1190 }
1191
1192 template <typename SourceVariant>
overlayCorners()1193 void RenderEngineTest::overlayCorners() {
1194 renderengine::DisplaySettings settings;
1195 settings.physicalDisplay = fullscreenRect();
1196 settings.clip = fullscreenRect();
1197 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1198
1199 std::vector<renderengine::LayerSettings> layersFirst;
1200
1201 renderengine::LayerSettings layerOne;
1202 layerOne.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1203 layerOne.geometry.boundaries =
1204 FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH / 3.0, DEFAULT_DISPLAY_HEIGHT / 3.0);
1205 SourceVariant::fillColor(layerOne, 1.0f, 0.0f, 0.0f, this);
1206 layerOne.alpha = 0.2;
1207
1208 layersFirst.push_back(layerOne);
1209 invokeDraw(settings, layersFirst);
1210 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3), 51, 0, 0, 51);
1211 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3 + 1, DEFAULT_DISPLAY_HEIGHT / 3 + 1,
1212 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1213 0, 0, 0, 0);
1214
1215 std::vector<renderengine::LayerSettings> layersSecond;
1216 renderengine::LayerSettings layerTwo;
1217 layerTwo.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1218 layerTwo.geometry.boundaries =
1219 FloatRect(DEFAULT_DISPLAY_WIDTH / 3.0, DEFAULT_DISPLAY_HEIGHT / 3.0,
1220 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT);
1221 SourceVariant::fillColor(layerTwo, 0.0f, 1.0f, 0.0f, this);
1222 layerTwo.alpha = 1.0f;
1223
1224 layersSecond.push_back(layerTwo);
1225 invokeDraw(settings, layersSecond);
1226
1227 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3), 0, 0, 0, 0);
1228 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3 + 1, DEFAULT_DISPLAY_HEIGHT / 3 + 1,
1229 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1230 0, 255, 0, 255);
1231 }
1232
fillRedBufferTextureTransform()1233 void RenderEngineTest::fillRedBufferTextureTransform() {
1234 renderengine::DisplaySettings settings;
1235 settings.physicalDisplay = fullscreenRect();
1236 settings.clip = Rect(1, 1);
1237 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1238
1239 std::vector<renderengine::LayerSettings> layers;
1240
1241 renderengine::LayerSettings layer;
1242 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1243 // Here will allocate a checker board texture, but transform texture
1244 // coordinates so that only the upper left is applied.
1245 const auto buf = allocateSourceBuffer(2, 2);
1246
1247 uint8_t* pixels;
1248 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1249 reinterpret_cast<void**>(&pixels));
1250 // Red top left, Green top right, Blue bottom left, Black bottom right
1251 pixels[0] = 255;
1252 pixels[1] = 0;
1253 pixels[2] = 0;
1254 pixels[3] = 255;
1255 pixels[4] = 0;
1256 pixels[5] = 255;
1257 pixels[6] = 0;
1258 pixels[7] = 255;
1259 pixels[8] = 0;
1260 pixels[9] = 0;
1261 pixels[10] = 255;
1262 pixels[11] = 255;
1263 buf->getBuffer()->unlock();
1264
1265 layer.source.buffer.buffer = buf;
1266 // Transform coordinates to only be inside the red quadrant.
1267 layer.source.buffer.textureTransform = mat4::scale(vec4(0.2f, 0.2f, 1.f, 1.f));
1268 layer.alpha = 1.0f;
1269 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1270
1271 layers.push_back(layer);
1272
1273 invokeDraw(settings, layers);
1274 }
1275
fillBufferTextureTransform()1276 void RenderEngineTest::fillBufferTextureTransform() {
1277 fillRedBufferTextureTransform();
1278 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
1279 }
1280
fillRedBufferWithPremultiplyAlpha()1281 void RenderEngineTest::fillRedBufferWithPremultiplyAlpha() {
1282 renderengine::DisplaySettings settings;
1283 settings.physicalDisplay = fullscreenRect();
1284 // Here logical space is 1x1
1285 settings.clip = Rect(1, 1);
1286
1287 std::vector<renderengine::LayerSettings> layers;
1288
1289 renderengine::LayerSettings layer;
1290 const auto buf = allocateSourceBuffer(1, 1);
1291
1292 uint8_t* pixels;
1293 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1294 reinterpret_cast<void**>(&pixels));
1295 pixels[0] = 255;
1296 pixels[1] = 0;
1297 pixels[2] = 0;
1298 pixels[3] = 255;
1299 buf->getBuffer()->unlock();
1300
1301 layer.source.buffer.buffer = buf;
1302 layer.source.buffer.usePremultipliedAlpha = true;
1303 layer.alpha = 0.5f;
1304 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1305
1306 layers.push_back(layer);
1307
1308 invokeDraw(settings, layers);
1309 }
1310
fillBufferWithPremultiplyAlpha()1311 void RenderEngineTest::fillBufferWithPremultiplyAlpha() {
1312 fillRedBufferWithPremultiplyAlpha();
1313 // Different backends and GPUs may round 255 * 0.5 = 127.5 differently, but
1314 // either 127 or 128 are acceptable. Checking both 127 and 128 with a
1315 // tolerance of 1 allows either 127 or 128 to pass, while preventing 126 or
1316 // 129 from erroneously passing.
1317 expectBufferColor(fullscreenRect(), 127, 0, 0, 127, 1);
1318 expectBufferColor(fullscreenRect(), 128, 0, 0, 128, 1);
1319 }
1320
fillRedBufferWithoutPremultiplyAlpha()1321 void RenderEngineTest::fillRedBufferWithoutPremultiplyAlpha() {
1322 renderengine::DisplaySettings settings;
1323 settings.physicalDisplay = fullscreenRect();
1324 // Here logical space is 1x1
1325 settings.clip = Rect(1, 1);
1326
1327 std::vector<renderengine::LayerSettings> layers;
1328
1329 renderengine::LayerSettings layer;
1330 const auto buf = allocateSourceBuffer(1, 1);
1331
1332 uint8_t* pixels;
1333 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1334 reinterpret_cast<void**>(&pixels));
1335 pixels[0] = 255;
1336 pixels[1] = 0;
1337 pixels[2] = 0;
1338 pixels[3] = 255;
1339 buf->getBuffer()->unlock();
1340
1341 layer.source.buffer.buffer = buf;
1342 layer.source.buffer.usePremultipliedAlpha = false;
1343 layer.alpha = 0.5f;
1344 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1345
1346 layers.push_back(layer);
1347
1348 invokeDraw(settings, layers);
1349 }
1350
fillBufferWithoutPremultiplyAlpha()1351 void RenderEngineTest::fillBufferWithoutPremultiplyAlpha() {
1352 fillRedBufferWithoutPremultiplyAlpha();
1353 expectBufferColor(fullscreenRect(), 128, 0, 0, 128, 1);
1354 }
1355
1356 template <typename SourceVariant>
drawShadow(const renderengine::LayerSettings & castingLayer,const ShadowSettings & shadow,const ubyte4 & casterColor,const ubyte4 & backgroundColor)1357 void RenderEngineTest::drawShadow(const renderengine::LayerSettings& castingLayer,
1358 const ShadowSettings& shadow, const ubyte4& casterColor,
1359 const ubyte4& backgroundColor) {
1360 renderengine::DisplaySettings settings;
1361 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1362 settings.physicalDisplay = fullscreenRect();
1363 settings.clip = fullscreenRect();
1364
1365 std::vector<renderengine::LayerSettings> layers;
1366
1367 // add background layer
1368 renderengine::LayerSettings bgLayer;
1369 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1370 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1371 ColorSourceVariant::fillColor(bgLayer, backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1372 backgroundColor.b / 255.0f, this);
1373 bgLayer.alpha = backgroundColor.a / 255.0f;
1374 layers.push_back(bgLayer);
1375
1376 // add shadow layer
1377 renderengine::LayerSettings shadowLayer;
1378 shadowLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1379 shadowLayer.geometry.boundaries = castingLayer.geometry.boundaries;
1380 shadowLayer.alpha = castingLayer.alpha;
1381 shadowLayer.shadow = shadow;
1382 layers.push_back(shadowLayer);
1383
1384 // add layer casting the shadow
1385 renderengine::LayerSettings layer = castingLayer;
1386 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1387 SourceVariant::fillColor(layer, casterColor.r / 255.0f, casterColor.g / 255.0f,
1388 casterColor.b / 255.0f, this);
1389 layers.push_back(layer);
1390
1391 invokeDraw(settings, layers);
1392 }
1393
drawShadowWithoutCaster(const FloatRect & castingBounds,const ShadowSettings & shadow,const ubyte4 & backgroundColor)1394 void RenderEngineTest::drawShadowWithoutCaster(const FloatRect& castingBounds,
1395 const ShadowSettings& shadow,
1396 const ubyte4& backgroundColor) {
1397 renderengine::DisplaySettings settings;
1398 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1399 settings.physicalDisplay = fullscreenRect();
1400 settings.clip = fullscreenRect();
1401
1402 std::vector<renderengine::LayerSettings> layers;
1403
1404 // add background layer
1405 renderengine::LayerSettings bgLayer;
1406 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1407 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1408 ColorSourceVariant::fillColor(bgLayer, backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1409 backgroundColor.b / 255.0f, this);
1410 bgLayer.alpha = backgroundColor.a / 255.0f;
1411 layers.push_back(bgLayer);
1412
1413 // add shadow layer
1414 renderengine::LayerSettings shadowLayer;
1415 shadowLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1416 shadowLayer.geometry.boundaries = castingBounds;
1417 shadowLayer.skipContentDraw = true;
1418 shadowLayer.alpha = 1.0f;
1419 ColorSourceVariant::fillColor(shadowLayer, 0, 0, 0, this);
1420 shadowLayer.shadow = shadow;
1421 layers.push_back(shadowLayer);
1422
1423 invokeDraw(settings, layers);
1424 }
1425
tonemap(ui::Dataspace sourceDataspace,std::function<vec3 (vec3)> eotf,std::function<vec3 (vec3,float)> scaleOotf)1426 void RenderEngineTest::tonemap(ui::Dataspace sourceDataspace, std::function<vec3(vec3)> eotf,
1427 std::function<vec3(vec3, float)> scaleOotf) {
1428 constexpr int32_t kGreyLevels = 256;
1429
1430 const auto rect = Rect(0, 0, kGreyLevels, 1);
1431
1432 constexpr float kMaxLuminance = 750.f;
1433 constexpr float kCurrentLuminanceNits = 500.f;
1434 const renderengine::DisplaySettings display{
1435 .physicalDisplay = rect,
1436 .clip = rect,
1437 .maxLuminance = kMaxLuminance,
1438 .currentLuminanceNits = kCurrentLuminanceNits,
1439 .outputDataspace = ui::Dataspace::DISPLAY_P3,
1440 };
1441
1442 auto buf = std::make_shared<
1443 renderengine::impl::
1444 ExternalTexture>(sp<GraphicBuffer>::make(kGreyLevels, 1,
1445 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1446 GRALLOC_USAGE_SW_READ_OFTEN |
1447 GRALLOC_USAGE_SW_WRITE_OFTEN |
1448 GRALLOC_USAGE_HW_RENDER |
1449 GRALLOC_USAGE_HW_TEXTURE,
1450 "input"),
1451 *mRE,
1452 renderengine::impl::ExternalTexture::Usage::READABLE |
1453 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
1454 ASSERT_EQ(0, buf->getBuffer()->initCheck());
1455 {
1456 uint8_t* pixels;
1457 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1458 reinterpret_cast<void**>(&pixels));
1459
1460 uint8_t color = 0;
1461 for (int32_t j = 0; j < buf->getBuffer()->getHeight(); j++) {
1462 uint8_t* dest = pixels + (buf->getBuffer()->getStride() * j * 4);
1463 for (int32_t i = 0; i < buf->getBuffer()->getWidth(); i++) {
1464 dest[0] = color;
1465 dest[1] = color;
1466 dest[2] = color;
1467 dest[3] = 255;
1468 color++;
1469 dest += 4;
1470 }
1471 }
1472 buf->getBuffer()->unlock();
1473 }
1474
1475 mBuffer = std::make_shared<
1476 renderengine::impl::
1477 ExternalTexture>(sp<GraphicBuffer>::make(kGreyLevels, 1,
1478 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1479 GRALLOC_USAGE_SW_READ_OFTEN |
1480 GRALLOC_USAGE_SW_WRITE_OFTEN |
1481 GRALLOC_USAGE_HW_RENDER |
1482 GRALLOC_USAGE_HW_TEXTURE,
1483 "output"),
1484 *mRE,
1485 renderengine::impl::ExternalTexture::Usage::READABLE |
1486 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
1487 ASSERT_EQ(0, mBuffer->getBuffer()->initCheck());
1488
1489 const renderengine::LayerSettings layer{.geometry.boundaries = rect.toFloatRect(),
1490 .source =
1491 renderengine::PixelSource{
1492 .buffer =
1493 renderengine::Buffer{
1494 .buffer =
1495 std::move(buf),
1496 .usePremultipliedAlpha =
1497 true,
1498 },
1499 },
1500 .alpha = 1.0f,
1501 .sourceDataspace = sourceDataspace};
1502
1503 std::vector<renderengine::LayerSettings> layers{layer};
1504 invokeDraw(display, layers);
1505
1506 ColorSpace displayP3 = ColorSpace::DisplayP3();
1507 ColorSpace bt2020 = ColorSpace::BT2020();
1508
1509 tonemap::Metadata metadata{.displayMaxLuminance = 750.0f};
1510
1511 auto generator = [=](Point location) {
1512 const double normColor = static_cast<double>(location.x) / (kGreyLevels - 1);
1513 const vec3 rgb = vec3(normColor, normColor, normColor);
1514
1515 const vec3 linearRGB = eotf(rgb);
1516
1517 const vec3 xyz = bt2020.getRGBtoXYZ() * linearRGB;
1518
1519 const vec3 scaledXYZ = scaleOotf(xyz, kCurrentLuminanceNits);
1520 const auto gains =
1521 tonemap::getToneMapper()
1522 ->lookupTonemapGain(static_cast<aidl::android::hardware::graphics::common::
1523 Dataspace>(sourceDataspace),
1524 static_cast<aidl::android::hardware::graphics::common::
1525 Dataspace>(
1526 ui::Dataspace::DISPLAY_P3),
1527 {tonemap::
1528 Color{.linearRGB =
1529 scaleOotf(linearRGB,
1530 kCurrentLuminanceNits),
1531 .xyz = scaledXYZ}},
1532 metadata);
1533 EXPECT_EQ(1, gains.size());
1534 const double gain = gains.front();
1535 const vec3 normalizedXYZ = scaledXYZ * gain / metadata.displayMaxLuminance;
1536
1537 const vec3 targetRGB = OETF_sRGB(displayP3.getXYZtoRGB() * normalizedXYZ) * 255;
1538 return ubyte4(static_cast<uint8_t>(targetRGB.r), static_cast<uint8_t>(targetRGB.g),
1539 static_cast<uint8_t>(targetRGB.b), 255);
1540 };
1541
1542 expectBufferColor(Rect(kGreyLevels, 1), generator, 2);
1543 }
1544
1545 // TODO: b/341728634 - Clean up conditional compilation.
1546 INSTANTIATE_TEST_SUITE_P(PerRenderEngineType, RenderEngineTest,
1547 testing::Values(std::make_shared<SkiaGLESRenderEngineFactory>(),
1548 std::make_shared<GaneshVkRenderEngineFactory>()
1549 #if COMPILE_GRAPHITE_RENDERENGINE
1550 ,
1551 std::make_shared<GraphiteVkRenderEngineFactory>()
1552 #endif
1553 ));
1554
TEST_P(RenderEngineTest,drawLayers_noLayersToDraw)1555 TEST_P(RenderEngineTest, drawLayers_noLayersToDraw) {
1556 if (!GetParam()->apiSupported()) {
1557 GTEST_SKIP();
1558 }
1559 initializeRenderEngine();
1560 drawEmptyLayers();
1561 }
1562
TEST_P(RenderEngineTest,drawLayers_fillRedBufferAndEmptyBuffer)1563 TEST_P(RenderEngineTest, drawLayers_fillRedBufferAndEmptyBuffer) {
1564 if (!GetParam()->apiSupported()) {
1565 GTEST_SKIP();
1566 }
1567 initializeRenderEngine();
1568 renderengine::DisplaySettings settings;
1569 settings.physicalDisplay = fullscreenRect();
1570 settings.clip = fullscreenRect();
1571 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1572
1573 // add a red layer
1574 renderengine::LayerSettings layerOne{
1575 .geometry.boundaries = fullscreenRect().toFloatRect(),
1576 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
1577 .alpha = 1.f,
1578 };
1579
1580 std::vector<renderengine::LayerSettings> layersFirst{layerOne};
1581 invokeDraw(settings, layersFirst);
1582 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
1583
1584 // re-draw with an empty layer above it, and we get a transparent black one
1585 std::vector<renderengine::LayerSettings> layersSecond;
1586 invokeDraw(settings, layersSecond);
1587 expectBufferColor(fullscreenRect(), 0, 0, 0, 0);
1588 }
1589
TEST_P(RenderEngineTest,drawLayers_withoutBuffers_withColorTransform)1590 TEST_P(RenderEngineTest, drawLayers_withoutBuffers_withColorTransform) {
1591 if (!GetParam()->apiSupported()) {
1592 GTEST_SKIP();
1593 }
1594 initializeRenderEngine();
1595
1596 renderengine::DisplaySettings settings;
1597 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1598 settings.physicalDisplay = fullscreenRect();
1599 settings.clip = fullscreenRect();
1600
1601 // 255, 255, 255, 255 is full opaque white.
1602 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
1603 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
1604 // Create layer with given color.
1605 renderengine::LayerSettings bgLayer;
1606 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1607 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1608 bgLayer.source.solidColor = half3(backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1609 backgroundColor.b / 255.0f);
1610 bgLayer.alpha = backgroundColor.a / 255.0f;
1611 // Transform the red color.
1612 bgLayer.colorTransform = mat4(-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
1613
1614 std::vector<renderengine::LayerSettings> layers;
1615 layers.push_back(bgLayer);
1616
1617 invokeDraw(settings, layers);
1618
1619 // Expect to see full opaque pixel (with inverted red from the transform).
1620 expectBufferColor(Rect(0, 0, 10, 10), 0.f, backgroundColor.g, backgroundColor.b,
1621 backgroundColor.a);
1622 }
1623
TEST_P(RenderEngineTest,drawLayers_nullOutputBuffer)1624 TEST_P(RenderEngineTest, drawLayers_nullOutputBuffer) {
1625 if (!GetParam()->apiSupported()) {
1626 GTEST_SKIP();
1627 }
1628 initializeRenderEngine();
1629
1630 renderengine::DisplaySettings settings;
1631 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1632 std::vector<renderengine::LayerSettings> layers;
1633 renderengine::LayerSettings layer;
1634 layer.geometry.boundaries = fullscreenRect().toFloatRect();
1635 BufferSourceVariant<ForceOpaqueBufferVariant>::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
1636 layers.push_back(layer);
1637 ftl::Future<FenceResult> future = mRE->drawLayers(settings, layers, nullptr, base::unique_fd());
1638
1639 ASSERT_TRUE(future.valid());
1640 auto result = future.get();
1641 ASSERT_FALSE(result.ok());
1642 ASSERT_EQ(BAD_VALUE, result.error());
1643 }
1644
TEST_P(RenderEngineTest,drawLayers_fillRedBuffer_colorSource)1645 TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_colorSource) {
1646 if (!GetParam()->apiSupported()) {
1647 GTEST_SKIP();
1648 }
1649 initializeRenderEngine();
1650 fillRedBuffer<ColorSourceVariant>();
1651 }
1652
TEST_P(RenderEngineTest,drawLayers_fillGreenBuffer_colorSource)1653 TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_colorSource) {
1654 if (!GetParam()->apiSupported()) {
1655 GTEST_SKIP();
1656 }
1657 initializeRenderEngine();
1658 fillGreenBuffer<ColorSourceVariant>();
1659 }
1660
TEST_P(RenderEngineTest,drawLayers_fillBlueBuffer_colorSource)1661 TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_colorSource) {
1662 if (!GetParam()->apiSupported()) {
1663 GTEST_SKIP();
1664 }
1665 initializeRenderEngine();
1666 fillBlueBuffer<ColorSourceVariant>();
1667 }
1668
TEST_P(RenderEngineTest,drawLayers_fillRedTransparentBuffer_colorSource)1669 TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_colorSource) {
1670 if (!GetParam()->apiSupported()) {
1671 GTEST_SKIP();
1672 }
1673 initializeRenderEngine();
1674 fillRedTransparentBuffer<ColorSourceVariant>();
1675 }
1676
TEST_P(RenderEngineTest,drawLayers_fillBufferPhysicalOffset_colorSource)1677 TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_colorSource) {
1678 if (!GetParam()->apiSupported()) {
1679 GTEST_SKIP();
1680 }
1681 initializeRenderEngine();
1682 fillBufferPhysicalOffset<ColorSourceVariant>();
1683 }
1684
TEST_P(RenderEngineTest,drawLayers_fillBufferCheckersRotate0_colorSource)1685 TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_colorSource) {
1686 if (!GetParam()->apiSupported()) {
1687 GTEST_SKIP();
1688 }
1689 initializeRenderEngine();
1690 fillBufferCheckersRotate0<ColorSourceVariant>();
1691 }
1692
TEST_P(RenderEngineTest,drawLayers_fillBufferCheckersRotate90_colorSource)1693 TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_colorSource) {
1694 if (!GetParam()->apiSupported()) {
1695 GTEST_SKIP();
1696 }
1697 initializeRenderEngine();
1698 fillBufferCheckersRotate90<ColorSourceVariant>();
1699 }
1700
TEST_P(RenderEngineTest,drawLayers_fillBufferCheckersRotate180_colorSource)1701 TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_colorSource) {
1702 if (!GetParam()->apiSupported()) {
1703 GTEST_SKIP();
1704 }
1705 initializeRenderEngine();
1706 fillBufferCheckersRotate180<ColorSourceVariant>();
1707 }
1708
TEST_P(RenderEngineTest,drawLayers_fillBufferCheckersRotate270_colorSource)1709 TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_colorSource) {
1710 if (!GetParam()->apiSupported()) {
1711 GTEST_SKIP();
1712 }
1713 initializeRenderEngine();
1714 fillBufferCheckersRotate270<ColorSourceVariant>();
1715 }
1716
TEST_P(RenderEngineTest,drawLayers_fillBufferLayerTransform_colorSource)1717 TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_colorSource) {
1718 if (!GetParam()->apiSupported()) {
1719 GTEST_SKIP();
1720 }
1721 initializeRenderEngine();
1722 fillBufferLayerTransform<ColorSourceVariant>();
1723 }
1724
TEST_P(RenderEngineTest,drawLayers_fillBufferColorTransform_colorSource)1725 TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_colorSource) {
1726 if (!GetParam()->apiSupported()) {
1727 GTEST_SKIP();
1728 }
1729 initializeRenderEngine();
1730 fillBufferColorTransform<ColorSourceVariant>();
1731 }
1732
TEST_P(RenderEngineTest,drawLayers_fillBufferColorTransform_sourceDataspace)1733 TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_sourceDataspace) {
1734 const auto& renderEngineFactory = GetParam();
1735 // skip for non color management
1736 if (!renderEngineFactory->apiSupported()) {
1737 GTEST_SKIP();
1738 }
1739
1740 initializeRenderEngine();
1741 fillBufferColorTransformAndSourceDataspace<ColorSourceVariant>();
1742 }
1743
TEST_P(RenderEngineTest,drawLayers_fillBufferColorTransform_outputDataspace)1744 TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_outputDataspace) {
1745 const auto& renderEngineFactory = GetParam();
1746 // skip for non color management
1747 if (!renderEngineFactory->apiSupported()) {
1748 GTEST_SKIP();
1749 }
1750
1751 initializeRenderEngine();
1752 fillBufferColorTransformAndOutputDataspace<ColorSourceVariant>();
1753 }
1754
TEST_P(RenderEngineTest,drawLayers_fillBufferRoundedCorners_colorSource)1755 TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_colorSource) {
1756 if (!GetParam()->apiSupported()) {
1757 GTEST_SKIP();
1758 }
1759 initializeRenderEngine();
1760 fillBufferWithRoundedCorners<ColorSourceVariant>();
1761 }
1762
TEST_P(RenderEngineTest,drawLayers_fillBufferColorTransformZeroLayerAlpha_colorSource)1763 TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_colorSource) {
1764 if (!GetParam()->apiSupported()) {
1765 GTEST_SKIP();
1766 }
1767 initializeRenderEngine();
1768 fillBufferColorTransformZeroLayerAlpha<ColorSourceVariant>();
1769 }
1770
TEST_P(RenderEngineTest,drawLayers_fillBufferAndBlurBackground_colorSource)1771 TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_colorSource) {
1772 if (!GetParam()->apiSupported()) {
1773 GTEST_SKIP();
1774 }
1775 initializeRenderEngine();
1776 fillBufferAndBlurBackground<ColorSourceVariant>();
1777 }
1778
TEST_P(RenderEngineTest,drawLayers_fillSmallLayerAndBlurBackground_colorSource)1779 TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_colorSource) {
1780 if (!GetParam()->apiSupported()) {
1781 GTEST_SKIP();
1782 }
1783 initializeRenderEngine();
1784 fillSmallLayerAndBlurBackground<ColorSourceVariant>();
1785 }
1786
TEST_P(RenderEngineTest,drawLayers_overlayCorners_colorSource)1787 TEST_P(RenderEngineTest, drawLayers_overlayCorners_colorSource) {
1788 if (!GetParam()->apiSupported()) {
1789 GTEST_SKIP();
1790 }
1791 initializeRenderEngine();
1792 overlayCorners<ColorSourceVariant>();
1793 }
1794
TEST_P(RenderEngineTest,drawLayers_fillRedBuffer_opaqueBufferSource)1795 TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_opaqueBufferSource) {
1796 if (!GetParam()->apiSupported()) {
1797 GTEST_SKIP();
1798 }
1799 initializeRenderEngine();
1800 fillRedBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1801 }
1802
TEST_P(RenderEngineTest,drawLayers_fillGreenBuffer_opaqueBufferSource)1803 TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_opaqueBufferSource) {
1804 if (!GetParam()->apiSupported()) {
1805 GTEST_SKIP();
1806 }
1807 initializeRenderEngine();
1808 fillGreenBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1809 }
1810
TEST_P(RenderEngineTest,drawLayers_fillBlueBuffer_opaqueBufferSource)1811 TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_opaqueBufferSource) {
1812 if (!GetParam()->apiSupported()) {
1813 GTEST_SKIP();
1814 }
1815 initializeRenderEngine();
1816 fillBlueBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1817 }
1818
TEST_P(RenderEngineTest,drawLayers_fillRedTransparentBuffer_opaqueBufferSource)1819 TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_opaqueBufferSource) {
1820 if (!GetParam()->apiSupported()) {
1821 GTEST_SKIP();
1822 }
1823 initializeRenderEngine();
1824 fillRedTransparentBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1825 }
1826
TEST_P(RenderEngineTest,drawLayers_fillBufferPhysicalOffset_opaqueBufferSource)1827 TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_opaqueBufferSource) {
1828 if (!GetParam()->apiSupported()) {
1829 GTEST_SKIP();
1830 }
1831 initializeRenderEngine();
1832 fillBufferPhysicalOffset<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1833 }
1834
TEST_P(RenderEngineTest,drawLayers_fillBufferCheckersRotate0_opaqueBufferSource)1835 TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_opaqueBufferSource) {
1836 if (!GetParam()->apiSupported()) {
1837 GTEST_SKIP();
1838 }
1839 initializeRenderEngine();
1840 fillBufferCheckersRotate0<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1841 }
1842
TEST_P(RenderEngineTest,drawLayers_fillBufferCheckersRotate90_opaqueBufferSource)1843 TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_opaqueBufferSource) {
1844 if (!GetParam()->apiSupported()) {
1845 GTEST_SKIP();
1846 }
1847 initializeRenderEngine();
1848 fillBufferCheckersRotate90<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1849 }
1850
TEST_P(RenderEngineTest,drawLayers_fillBufferCheckersRotate180_opaqueBufferSource)1851 TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_opaqueBufferSource) {
1852 if (!GetParam()->apiSupported()) {
1853 GTEST_SKIP();
1854 }
1855 initializeRenderEngine();
1856 fillBufferCheckersRotate180<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1857 }
1858
TEST_P(RenderEngineTest,drawLayers_fillBufferCheckersRotate270_opaqueBufferSource)1859 TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_opaqueBufferSource) {
1860 if (!GetParam()->apiSupported()) {
1861 GTEST_SKIP();
1862 }
1863 initializeRenderEngine();
1864 fillBufferCheckersRotate270<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1865 }
1866
TEST_P(RenderEngineTest,drawLayers_fillBufferLayerTransform_opaqueBufferSource)1867 TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_opaqueBufferSource) {
1868 if (!GetParam()->apiSupported()) {
1869 GTEST_SKIP();
1870 }
1871 initializeRenderEngine();
1872 fillBufferLayerTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1873 }
1874
TEST_P(RenderEngineTest,drawLayers_fillBufferColorTransform_opaqueBufferSource)1875 TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_opaqueBufferSource) {
1876 if (!GetParam()->apiSupported()) {
1877 GTEST_SKIP();
1878 }
1879 initializeRenderEngine();
1880 fillBufferColorTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1881 }
1882
TEST_P(RenderEngineTest,drawLayers_fillBufferColorTransformAndSourceDataspace_opaqueBufferSource)1883 TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndSourceDataspace_opaqueBufferSource) {
1884 const auto& renderEngineFactory = GetParam();
1885 // skip for non color management
1886 if (!renderEngineFactory->apiSupported()) {
1887 GTEST_SKIP();
1888 }
1889
1890 initializeRenderEngine();
1891 fillBufferColorTransformAndSourceDataspace<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1892 }
1893
TEST_P(RenderEngineTest,drawLayers_fillBufferColorTransformAndOutputDataspace_opaqueBufferSource)1894 TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndOutputDataspace_opaqueBufferSource) {
1895 const auto& renderEngineFactory = GetParam();
1896 // skip for non color management
1897 if (!renderEngineFactory->apiSupported()) {
1898 GTEST_SKIP();
1899 }
1900
1901 initializeRenderEngine();
1902 fillBufferColorTransformAndOutputDataspace<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1903 }
1904
TEST_P(RenderEngineTest,drawLayers_fillBufferRoundedCorners_opaqueBufferSource)1905 TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_opaqueBufferSource) {
1906 if (!GetParam()->apiSupported()) {
1907 GTEST_SKIP();
1908 }
1909 initializeRenderEngine();
1910 fillBufferWithRoundedCorners<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1911 }
1912
TEST_P(RenderEngineTest,drawLayers_fillBufferColorTransformZeroLayerAlpha_opaqueBufferSource)1913 TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_opaqueBufferSource) {
1914 if (!GetParam()->apiSupported()) {
1915 GTEST_SKIP();
1916 }
1917 initializeRenderEngine();
1918 fillBufferColorTransformZeroLayerAlpha<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1919 }
1920
TEST_P(RenderEngineTest,drawLayers_fillBufferAndBlurBackground_opaqueBufferSource)1921 TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_opaqueBufferSource) {
1922 if (!GetParam()->apiSupported()) {
1923 GTEST_SKIP();
1924 }
1925 initializeRenderEngine();
1926 fillBufferAndBlurBackground<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1927 }
1928
TEST_P(RenderEngineTest,drawLayers_fillSmallLayerAndBlurBackground_opaqueBufferSource)1929 TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_opaqueBufferSource) {
1930 if (!GetParam()->apiSupported()) {
1931 GTEST_SKIP();
1932 }
1933 initializeRenderEngine();
1934 fillSmallLayerAndBlurBackground<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1935 }
1936
TEST_P(RenderEngineTest,drawLayers_overlayCorners_opaqueBufferSource)1937 TEST_P(RenderEngineTest, drawLayers_overlayCorners_opaqueBufferSource) {
1938 if (!GetParam()->apiSupported()) {
1939 GTEST_SKIP();
1940 }
1941 initializeRenderEngine();
1942 overlayCorners<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1943 }
1944
TEST_P(RenderEngineTest,drawLayers_fillRedBuffer_bufferSource)1945 TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_bufferSource) {
1946 if (!GetParam()->apiSupported()) {
1947 GTEST_SKIP();
1948 }
1949 initializeRenderEngine();
1950 fillRedBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1951 }
1952
TEST_P(RenderEngineTest,drawLayers_fillGreenBuffer_bufferSource)1953 TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_bufferSource) {
1954 if (!GetParam()->apiSupported()) {
1955 GTEST_SKIP();
1956 }
1957 initializeRenderEngine();
1958 fillGreenBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1959 }
1960
TEST_P(RenderEngineTest,drawLayers_fillBlueBuffer_bufferSource)1961 TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_bufferSource) {
1962 if (!GetParam()->apiSupported()) {
1963 GTEST_SKIP();
1964 }
1965 initializeRenderEngine();
1966 fillBlueBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1967 }
1968
TEST_P(RenderEngineTest,drawLayers_fillRedTransparentBuffer_bufferSource)1969 TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_bufferSource) {
1970 if (!GetParam()->apiSupported()) {
1971 GTEST_SKIP();
1972 }
1973 initializeRenderEngine();
1974 fillRedTransparentBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1975 }
1976
TEST_P(RenderEngineTest,drawLayers_fillBufferPhysicalOffset_bufferSource)1977 TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_bufferSource) {
1978 if (!GetParam()->apiSupported()) {
1979 GTEST_SKIP();
1980 }
1981 initializeRenderEngine();
1982 fillBufferPhysicalOffset<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1983 }
1984
TEST_P(RenderEngineTest,drawLayers_fillBufferCheckersRotate0_bufferSource)1985 TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_bufferSource) {
1986 if (!GetParam()->apiSupported()) {
1987 GTEST_SKIP();
1988 }
1989 initializeRenderEngine();
1990 fillBufferCheckersRotate0<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1991 }
1992
TEST_P(RenderEngineTest,drawLayers_fillBufferCheckersRotate90_bufferSource)1993 TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_bufferSource) {
1994 if (!GetParam()->apiSupported()) {
1995 GTEST_SKIP();
1996 }
1997 initializeRenderEngine();
1998 fillBufferCheckersRotate90<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1999 }
2000
TEST_P(RenderEngineTest,drawLayers_fillBufferCheckersRotate180_bufferSource)2001 TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_bufferSource) {
2002 if (!GetParam()->apiSupported()) {
2003 GTEST_SKIP();
2004 }
2005 initializeRenderEngine();
2006 fillBufferCheckersRotate180<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2007 }
2008
TEST_P(RenderEngineTest,drawLayers_fillBufferCheckersRotate270_bufferSource)2009 TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_bufferSource) {
2010 if (!GetParam()->apiSupported()) {
2011 GTEST_SKIP();
2012 }
2013 initializeRenderEngine();
2014 fillBufferCheckersRotate270<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2015 }
2016
TEST_P(RenderEngineTest,drawLayers_fillBufferLayerTransform_bufferSource)2017 TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_bufferSource) {
2018 if (!GetParam()->apiSupported()) {
2019 GTEST_SKIP();
2020 }
2021 initializeRenderEngine();
2022 fillBufferLayerTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2023 }
2024
TEST_P(RenderEngineTest,drawLayers_fillBufferColorTransform_bufferSource)2025 TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_bufferSource) {
2026 if (!GetParam()->apiSupported()) {
2027 GTEST_SKIP();
2028 }
2029 initializeRenderEngine();
2030 fillBufferColorTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2031 }
2032
TEST_P(RenderEngineTest,drawLayers_fillBufferColorTransformAndSourceDataspace_bufferSource)2033 TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndSourceDataspace_bufferSource) {
2034 const auto& renderEngineFactory = GetParam();
2035 // skip for non color management
2036 if (!renderEngineFactory->apiSupported()) {
2037 GTEST_SKIP();
2038 }
2039
2040 initializeRenderEngine();
2041 fillBufferColorTransformAndSourceDataspace<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2042 }
2043
TEST_P(RenderEngineTest,drawLayers_fillBufferColorTransformAndOutputDataspace_bufferSource)2044 TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndOutputDataspace_bufferSource) {
2045 const auto& renderEngineFactory = GetParam();
2046 // skip for non color management
2047 if (!renderEngineFactory->apiSupported()) {
2048 GTEST_SKIP();
2049 }
2050
2051 initializeRenderEngine();
2052 fillBufferColorTransformAndOutputDataspace<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2053 }
2054
TEST_P(RenderEngineTest,drawLayers_fillBufferRoundedCorners_bufferSource)2055 TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_bufferSource) {
2056 if (!GetParam()->apiSupported()) {
2057 GTEST_SKIP();
2058 }
2059 initializeRenderEngine();
2060 fillBufferWithRoundedCorners<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2061 }
2062
TEST_P(RenderEngineTest,drawLayers_fillBufferColorTransformZeroLayerAlpha_bufferSource)2063 TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_bufferSource) {
2064 if (!GetParam()->apiSupported()) {
2065 GTEST_SKIP();
2066 }
2067 initializeRenderEngine();
2068 fillBufferColorTransformZeroLayerAlpha<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2069 }
2070
TEST_P(RenderEngineTest,drawLayers_fillBufferAndBlurBackground_bufferSource)2071 TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_bufferSource) {
2072 if (!GetParam()->apiSupported()) {
2073 GTEST_SKIP();
2074 }
2075 initializeRenderEngine();
2076 fillBufferAndBlurBackground<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2077 }
2078
TEST_P(RenderEngineTest,drawLayers_fillSmallLayerAndBlurBackground_bufferSource)2079 TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_bufferSource) {
2080 if (!GetParam()->apiSupported()) {
2081 GTEST_SKIP();
2082 }
2083 initializeRenderEngine();
2084 fillSmallLayerAndBlurBackground<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2085 }
2086
TEST_P(RenderEngineTest,drawLayers_overlayCorners_bufferSource)2087 TEST_P(RenderEngineTest, drawLayers_overlayCorners_bufferSource) {
2088 if (!GetParam()->apiSupported()) {
2089 GTEST_SKIP();
2090 }
2091 initializeRenderEngine();
2092 overlayCorners<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
2093 }
2094
TEST_P(RenderEngineTest,drawLayers_fillBufferTextureTransform)2095 TEST_P(RenderEngineTest, drawLayers_fillBufferTextureTransform) {
2096 if (!GetParam()->apiSupported()) {
2097 GTEST_SKIP();
2098 }
2099 initializeRenderEngine();
2100 fillBufferTextureTransform();
2101 }
2102
TEST_P(RenderEngineTest,drawLayers_fillBuffer_premultipliesAlpha)2103 TEST_P(RenderEngineTest, drawLayers_fillBuffer_premultipliesAlpha) {
2104 if (!GetParam()->apiSupported()) {
2105 GTEST_SKIP();
2106 }
2107 initializeRenderEngine();
2108 fillBufferWithPremultiplyAlpha();
2109 }
2110
TEST_P(RenderEngineTest,drawLayers_fillBuffer_withoutPremultiplyingAlpha)2111 TEST_P(RenderEngineTest, drawLayers_fillBuffer_withoutPremultiplyingAlpha) {
2112 if (!GetParam()->apiSupported()) {
2113 GTEST_SKIP();
2114 }
2115 initializeRenderEngine();
2116 fillBufferWithoutPremultiplyAlpha();
2117 }
2118
TEST_P(RenderEngineTest,drawLayers_fillShadow_castsWithoutCasterLayer)2119 TEST_P(RenderEngineTest, drawLayers_fillShadow_castsWithoutCasterLayer) {
2120 if (!GetParam()->apiSupported()) {
2121 GTEST_SKIP();
2122 }
2123 initializeRenderEngine();
2124
2125 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2126 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
2127 const float shadowLength = 5.0f;
2128 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2129 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2130 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2131 shadowLength, false /* casterIsTranslucent */);
2132
2133 drawShadowWithoutCaster(casterBounds.toFloatRect(), settings, backgroundColor);
2134 expectShadowColorWithoutCaster(casterBounds.toFloatRect(), settings, backgroundColor);
2135 }
2136
TEST_P(RenderEngineTest,drawLayers_fillShadow_casterLayerMinSize)2137 TEST_P(RenderEngineTest, drawLayers_fillShadow_casterLayerMinSize) {
2138 if (!GetParam()->apiSupported()) {
2139 GTEST_SKIP();
2140 }
2141 initializeRenderEngine();
2142
2143 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2144 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2145 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2146 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
2147 const float shadowLength = 5.0f;
2148 Rect casterBounds(1, 1);
2149 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2150 renderengine::LayerSettings castingLayer;
2151 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2152 castingLayer.alpha = 1.0f;
2153 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2154 shadowLength, false /* casterIsTranslucent */);
2155
2156 drawShadow<ColorSourceVariant>(castingLayer, settings, casterColor, backgroundColor);
2157 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2158 }
2159
TEST_P(RenderEngineTest,drawLayers_fillShadow_casterColorLayer)2160 TEST_P(RenderEngineTest, drawLayers_fillShadow_casterColorLayer) {
2161 if (!GetParam()->apiSupported()) {
2162 GTEST_SKIP();
2163 }
2164 initializeRenderEngine();
2165
2166 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2167 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2168 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2169 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
2170 const float shadowLength = 5.0f;
2171 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2172 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2173 renderengine::LayerSettings castingLayer;
2174 castingLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2175 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2176 castingLayer.alpha = 1.0f;
2177 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2178 shadowLength, false /* casterIsTranslucent */);
2179
2180 drawShadow<ColorSourceVariant>(castingLayer, settings, casterColor, backgroundColor);
2181 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2182 }
2183
TEST_P(RenderEngineTest,drawLayers_fillShadow_casterOpaqueBufferLayer)2184 TEST_P(RenderEngineTest, drawLayers_fillShadow_casterOpaqueBufferLayer) {
2185 if (!GetParam()->apiSupported()) {
2186 GTEST_SKIP();
2187 }
2188 initializeRenderEngine();
2189
2190 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2191 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2192 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2193 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
2194 const float shadowLength = 5.0f;
2195 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2196 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2197 renderengine::LayerSettings castingLayer;
2198 castingLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2199 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2200 castingLayer.alpha = 1.0f;
2201 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2202 shadowLength, false /* casterIsTranslucent */);
2203
2204 drawShadow<BufferSourceVariant<ForceOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2205 backgroundColor);
2206 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2207 }
2208
TEST_P(RenderEngineTest,drawLayers_fillShadow_casterWithRoundedCorner)2209 TEST_P(RenderEngineTest, drawLayers_fillShadow_casterWithRoundedCorner) {
2210 if (!GetParam()->apiSupported()) {
2211 GTEST_SKIP();
2212 }
2213 initializeRenderEngine();
2214
2215 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2216 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2217 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2218 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
2219 const float shadowLength = 5.0f;
2220 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2221 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2222 renderengine::LayerSettings castingLayer;
2223 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2224 castingLayer.geometry.roundedCornersRadius = {3.0f, 3.0f};
2225 castingLayer.geometry.roundedCornersCrop = casterBounds.toFloatRect();
2226 castingLayer.alpha = 1.0f;
2227 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2228 shadowLength, false /* casterIsTranslucent */);
2229
2230 drawShadow<BufferSourceVariant<ForceOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2231 backgroundColor);
2232 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2233 }
2234
TEST_P(RenderEngineTest,drawLayers_fillShadow_translucentCasterWithAlpha)2235 TEST_P(RenderEngineTest, drawLayers_fillShadow_translucentCasterWithAlpha) {
2236 if (!GetParam()->apiSupported()) {
2237 GTEST_SKIP();
2238 }
2239 initializeRenderEngine();
2240
2241 const ubyte4 casterColor(255, 0, 0, 255);
2242 const ubyte4 backgroundColor(255, 255, 255, 255);
2243 const float shadowLength = 5.0f;
2244 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2245 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2246 renderengine::LayerSettings castingLayer;
2247 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2248 castingLayer.alpha = 0.5f;
2249 ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
2250 shadowLength, true /* casterIsTranslucent */);
2251
2252 drawShadow<BufferSourceVariant<RelaxOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2253 backgroundColor);
2254
2255 // verify only the background since the shadow will draw behind the caster
2256 const float shadowInset = settings.length * -1.0f;
2257 const Rect casterWithShadow =
2258 Rect(casterBounds).inset(shadowInset, shadowInset, shadowInset, shadowInset);
2259 const Region backgroundRegion = Region(fullscreenRect()).subtractSelf(casterWithShadow);
2260 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
2261 backgroundColor.a);
2262 }
2263
TEST_P(RenderEngineTest,cleanupPostRender_cleansUpOnce)2264 TEST_P(RenderEngineTest, cleanupPostRender_cleansUpOnce) {
2265 if (!GetParam()->apiSupported()) {
2266 GTEST_SKIP();
2267 }
2268 initializeRenderEngine();
2269
2270 renderengine::DisplaySettings settings;
2271 settings.physicalDisplay = fullscreenRect();
2272 settings.clip = fullscreenRect();
2273 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2274
2275 std::vector<renderengine::LayerSettings> layers;
2276 renderengine::LayerSettings layer;
2277 layer.geometry.boundaries = fullscreenRect().toFloatRect();
2278 BufferSourceVariant<ForceOpaqueBufferVariant>::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
2279 layer.alpha = 1.0;
2280 layers.push_back(layer);
2281
2282 ftl::Future<FenceResult> futureOne =
2283 mRE->drawLayers(settings, layers, mBuffer, base::unique_fd());
2284 ASSERT_TRUE(futureOne.valid());
2285 auto resultOne = futureOne.get();
2286 ASSERT_TRUE(resultOne.ok());
2287 auto fenceOne = resultOne.value();
2288
2289 ftl::Future<FenceResult> futureTwo =
2290 mRE->drawLayers(settings, layers, mBuffer, base::unique_fd(fenceOne->dup()));
2291 ASSERT_TRUE(futureTwo.valid());
2292 auto resultTwo = futureTwo.get();
2293 ASSERT_TRUE(resultTwo.ok());
2294 auto fenceTwo = resultTwo.value();
2295 fenceTwo->waitForever(LOG_TAG);
2296
2297 // Only cleanup the first time.
2298 if (mRE->canSkipPostRenderCleanup()) {
2299 // Skia's Vk backend may keep the texture alive beyond drawLayersInternal, so
2300 // it never gets added to the cleanup list. In those cases, we can skip.
2301 EXPECT_TRUE(GetParam()->graphicsApi() == renderengine::RenderEngine::GraphicsApi::VK);
2302 } else {
2303 mRE->cleanupPostRender();
2304 EXPECT_TRUE(mRE->canSkipPostRenderCleanup());
2305 }
2306 }
2307
TEST_P(RenderEngineTest,testRoundedCornersCrop)2308 TEST_P(RenderEngineTest, testRoundedCornersCrop) {
2309 if (!GetParam()->apiSupported()) {
2310 GTEST_SKIP();
2311 }
2312 initializeRenderEngine();
2313
2314 renderengine::DisplaySettings settings;
2315 settings.physicalDisplay = fullscreenRect();
2316 settings.clip = fullscreenRect();
2317 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2318
2319 std::vector<renderengine::LayerSettings> layers;
2320
2321 renderengine::LayerSettings redLayer;
2322 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2323 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
2324 redLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
2325
2326 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2327 // Red background.
2328 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2329 redLayer.alpha = 1.0f;
2330
2331 layers.push_back(redLayer);
2332
2333 // Green layer with 1/3 size.
2334 renderengine::LayerSettings greenLayer;
2335 greenLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2336 greenLayer.geometry.boundaries = fullscreenRect().toFloatRect();
2337 greenLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
2338 // Bottom right corner is not going to be rounded.
2339 greenLayer.geometry.roundedCornersCrop =
2340 Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3, DEFAULT_DISPLAY_HEIGHT,
2341 DEFAULT_DISPLAY_HEIGHT)
2342 .toFloatRect();
2343 greenLayer.source.solidColor = half3(0.0f, 1.0f, 0.0f);
2344 greenLayer.alpha = 1.0f;
2345
2346 layers.push_back(greenLayer);
2347
2348 invokeDraw(settings, layers);
2349
2350 // Corners should be ignored...
2351 // Screen size: width is 128, height is 256.
2352 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 0);
2353 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, 0, DEFAULT_DISPLAY_WIDTH, 1), 0, 0, 0, 0);
2354 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT - 1, 1, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
2355 // Bottom right corner is kept out of the clipping, and it's green.
2356 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1,
2357 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
2358 0, 255, 0, 255);
2359 }
2360
TEST_P(RenderEngineTest,testRoundedCornersParentCrop)2361 TEST_P(RenderEngineTest, testRoundedCornersParentCrop) {
2362 if (!GetParam()->apiSupported()) {
2363 GTEST_SKIP();
2364 }
2365 initializeRenderEngine();
2366
2367 renderengine::DisplaySettings settings;
2368 settings.physicalDisplay = fullscreenRect();
2369 settings.clip = fullscreenRect();
2370 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2371
2372 std::vector<renderengine::LayerSettings> layers;
2373
2374 renderengine::LayerSettings redLayer;
2375 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2376 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
2377 redLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
2378 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2379 // Red background.
2380 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2381 redLayer.alpha = 1.0f;
2382
2383 layers.push_back(redLayer);
2384
2385 // Green layer with 1/2 size with parent crop rect.
2386 renderengine::LayerSettings greenLayer = redLayer;
2387 greenLayer.geometry.boundaries =
2388 FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT / 2);
2389 greenLayer.source.solidColor = half3(0.0f, 1.0f, 0.0f);
2390
2391 layers.push_back(greenLayer);
2392
2393 invokeDraw(settings, layers);
2394
2395 // Due to roundedCornersRadius, the corners are untouched.
2396 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2397 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2398 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2399 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2400
2401 // top middle should be green and the bottom middle red
2402 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, 0), 0, 255, 0, 255);
2403 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0, 255);
2404
2405 // the bottom edge of the green layer should not be rounded
2406 expectBufferColor(Point(0, (DEFAULT_DISPLAY_HEIGHT / 2) - 1), 0, 255, 0, 255);
2407 }
2408
TEST_P(RenderEngineTest,testRoundedCornersParentCropSmallBounds)2409 TEST_P(RenderEngineTest, testRoundedCornersParentCropSmallBounds) {
2410 if (!GetParam()->apiSupported()) {
2411 GTEST_SKIP();
2412 }
2413 initializeRenderEngine();
2414
2415 renderengine::DisplaySettings settings;
2416 settings.physicalDisplay = fullscreenRect();
2417 settings.clip = fullscreenRect();
2418 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2419
2420 std::vector<renderengine::LayerSettings> layers;
2421
2422 renderengine::LayerSettings redLayer;
2423 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2424 redLayer.geometry.boundaries = FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, 32);
2425 redLayer.geometry.roundedCornersRadius = {64.0f, 64.0f};
2426 redLayer.geometry.roundedCornersCrop = FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, 128);
2427 // Red background.
2428 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2429 redLayer.alpha = 1.0f;
2430
2431 layers.push_back(redLayer);
2432 invokeDraw(settings, layers);
2433
2434 // Due to roundedCornersRadius, the top corners are untouched.
2435 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2436 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2437
2438 // ensure that the entire height of the red layer was clipped by the rounded corners crop.
2439 expectBufferColor(Point(0, 31), 0, 0, 0, 0);
2440 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 31), 0, 0, 0, 0);
2441
2442 // the bottom middle should be red
2443 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, 31), 255, 0, 0, 255);
2444 }
2445
TEST_P(RenderEngineTest,testRoundedCornersXY)2446 TEST_P(RenderEngineTest, testRoundedCornersXY) {
2447 if (!GetParam()->apiSupported()) {
2448 GTEST_SKIP();
2449 }
2450
2451 initializeRenderEngine();
2452
2453 renderengine::DisplaySettings settings;
2454 settings.physicalDisplay = fullscreenRect();
2455 settings.clip = fullscreenRect();
2456 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2457
2458 std::vector<renderengine::LayerSettings> layers;
2459
2460 renderengine::LayerSettings redLayer;
2461 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2462 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
2463 redLayer.geometry.roundedCornersRadius = {5.0f, 20.0f};
2464 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2465 // Red background.
2466 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2467 redLayer.alpha = 1.0f;
2468
2469 layers.push_back(redLayer);
2470
2471 invokeDraw(settings, layers);
2472
2473 // Due to roundedCornersRadius, the corners are untouched.
2474 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2475 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2476 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2477 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2478
2479 // Y-axis draws a larger radius, check that its untouched as well
2480 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 5), 0, 0, 0, 0);
2481 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 5), 0, 0, 0, 0);
2482 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 5), 0, 0, 0, 0);
2483 expectBufferColor(Point(0, 5), 0, 0, 0, 0);
2484
2485 // middle should be red
2486 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0, 255);
2487 }
2488
TEST_P(RenderEngineTest,testClear)2489 TEST_P(RenderEngineTest, testClear) {
2490 if (!GetParam()->apiSupported()) {
2491 GTEST_SKIP();
2492 }
2493 initializeRenderEngine();
2494
2495 const auto rect = fullscreenRect();
2496 const renderengine::DisplaySettings display{
2497 .physicalDisplay = rect,
2498 .clip = rect,
2499 };
2500
2501 const renderengine::LayerSettings redLayer{
2502 .geometry.boundaries = rect.toFloatRect(),
2503 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
2504 .alpha = 1.0f,
2505 };
2506
2507 // This mimics prepareClearClientComposition. This layer should overwrite
2508 // the redLayer, so that the buffer is transparent, rather than red.
2509 const renderengine::LayerSettings clearLayer{
2510 .geometry.boundaries = rect.toFloatRect(),
2511 .source.solidColor = half3(0.0f, 0.0f, 0.0f),
2512 .alpha = 0.0f,
2513 .disableBlending = true,
2514 };
2515
2516 std::vector<renderengine::LayerSettings> layers{redLayer, clearLayer};
2517 invokeDraw(display, layers);
2518 expectBufferColor(rect, 0, 0, 0, 0);
2519 }
2520
TEST_P(RenderEngineTest,testDisableBlendingBuffer)2521 TEST_P(RenderEngineTest, testDisableBlendingBuffer) {
2522 if (!GetParam()->apiSupported()) {
2523 GTEST_SKIP();
2524 }
2525 initializeRenderEngine();
2526
2527 const auto rect = Rect(0, 0, 1, 1);
2528 const renderengine::DisplaySettings display{
2529 .physicalDisplay = rect,
2530 .clip = rect,
2531 };
2532
2533 const renderengine::LayerSettings redLayer{
2534 .geometry.boundaries = rect.toFloatRect(),
2535 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
2536 .alpha = 1.0f,
2537 };
2538
2539 // The next layer will overwrite redLayer with a GraphicBuffer that is green
2540 // applied with a translucent alpha.
2541 const auto buf = allocateSourceBuffer(1, 1);
2542 {
2543 uint8_t* pixels;
2544 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2545 reinterpret_cast<void**>(&pixels));
2546 pixels[0] = 0;
2547 pixels[1] = 255;
2548 pixels[2] = 0;
2549 pixels[3] = 255;
2550 buf->getBuffer()->unlock();
2551 }
2552
2553 const renderengine::LayerSettings greenLayer{
2554 .geometry.boundaries = rect.toFloatRect(),
2555 .source =
2556 renderengine::PixelSource{
2557 .buffer =
2558 renderengine::Buffer{
2559 .buffer = buf,
2560 .usePremultipliedAlpha = true,
2561 },
2562 },
2563 .alpha = 0.5f,
2564 .disableBlending = true,
2565 };
2566
2567 std::vector<renderengine::LayerSettings> layers{redLayer, greenLayer};
2568 invokeDraw(display, layers);
2569 expectBufferColor(rect, 0, 128, 0, 128);
2570 }
2571
TEST_P(RenderEngineTest,testDimming)2572 TEST_P(RenderEngineTest, testDimming) {
2573 if (!GetParam()->apiSupported()) {
2574 GTEST_SKIP();
2575 }
2576 initializeRenderEngine();
2577
2578 const ui::Dataspace dataspace = ui::Dataspace::V0_SRGB_LINEAR;
2579
2580 const auto displayRect = Rect(3, 1);
2581 const renderengine::DisplaySettings display{
2582 .physicalDisplay = displayRect,
2583 .clip = displayRect,
2584 .outputDataspace = dataspace,
2585 .targetLuminanceNits = 1000.f,
2586 };
2587
2588 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2589 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2590 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2591
2592 const renderengine::LayerSettings greenLayer{
2593 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2594 .source =
2595 renderengine::PixelSource{
2596 .buffer =
2597 renderengine::Buffer{
2598 .buffer = greenBuffer,
2599 .usePremultipliedAlpha = true,
2600 },
2601 },
2602 .alpha = 1.0f,
2603 .sourceDataspace = dataspace,
2604 .whitePointNits = 200.f,
2605 };
2606
2607 const renderengine::LayerSettings blueLayer{
2608 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2609 .source =
2610 renderengine::PixelSource{
2611 .buffer =
2612 renderengine::Buffer{
2613 .buffer = blueBuffer,
2614 .usePremultipliedAlpha = true,
2615 },
2616 },
2617 .alpha = 1.0f,
2618 .sourceDataspace = dataspace,
2619 .whitePointNits = 1000.f / 51.f,
2620 };
2621
2622 const renderengine::LayerSettings redLayer{
2623 .geometry.boundaries = FloatRect(2.f, 0.f, 3.f, 1.f),
2624 .source =
2625 renderengine::PixelSource{
2626 .buffer =
2627 renderengine::Buffer{
2628 .buffer = redBuffer,
2629 .usePremultipliedAlpha = true,
2630 },
2631 },
2632 .alpha = 1.0f,
2633 .sourceDataspace = dataspace,
2634 // When the white point is not set for a layer, just ignore it and treat it as the same
2635 // as the max layer
2636 .whitePointNits = -1.f,
2637 };
2638
2639 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer, redLayer};
2640 invokeDraw(display, layers);
2641
2642 expectBufferColor(Rect(1, 1), 0, 51, 0, 255, 1);
2643 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 5, 255, 1);
2644 expectBufferColor(Rect(2, 0, 3, 1), 51, 0, 0, 255, 1);
2645 }
2646
TEST_P(RenderEngineTest,testDimming_inGammaSpace)2647 TEST_P(RenderEngineTest, testDimming_inGammaSpace) {
2648 if (!GetParam()->apiSupported()) {
2649 GTEST_SKIP();
2650 }
2651 initializeRenderEngine();
2652
2653 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2654 ui::Dataspace::TRANSFER_GAMMA2_2 |
2655 ui::Dataspace::RANGE_FULL);
2656
2657 const auto displayRect = Rect(3, 1);
2658 const renderengine::DisplaySettings display{
2659 .physicalDisplay = displayRect,
2660 .clip = displayRect,
2661 .outputDataspace = dataspace,
2662 .targetLuminanceNits = 1000.f,
2663 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2664 };
2665
2666 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2667 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2668 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2669
2670 const renderengine::LayerSettings greenLayer{
2671 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2672 .source =
2673 renderengine::PixelSource{
2674 .buffer =
2675 renderengine::Buffer{
2676 .buffer = greenBuffer,
2677 .usePremultipliedAlpha = true,
2678 },
2679 },
2680 .alpha = 1.0f,
2681 .sourceDataspace = dataspace,
2682 .whitePointNits = 200.f,
2683 };
2684
2685 const renderengine::LayerSettings blueLayer{
2686 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2687 .source =
2688 renderengine::PixelSource{
2689 .buffer =
2690 renderengine::Buffer{
2691 .buffer = blueBuffer,
2692 .usePremultipliedAlpha = true,
2693 },
2694 },
2695 .alpha = 1.0f,
2696 .sourceDataspace = dataspace,
2697 .whitePointNits = 1000.f / 51.f,
2698 };
2699
2700 const renderengine::LayerSettings redLayer{
2701 .geometry.boundaries = FloatRect(2.f, 0.f, 3.f, 1.f),
2702 .source =
2703 renderengine::PixelSource{
2704 .buffer =
2705 renderengine::Buffer{
2706 .buffer = redBuffer,
2707 .usePremultipliedAlpha = true,
2708 },
2709 },
2710 .alpha = 1.0f,
2711 .sourceDataspace = dataspace,
2712 // When the white point is not set for a layer, just ignore it and treat it as the same
2713 // as the max layer
2714 .whitePointNits = -1.f,
2715 };
2716
2717 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer, redLayer};
2718 invokeDraw(display, layers);
2719
2720 expectBufferColor(Rect(1, 1), 0, 122, 0, 255, 1);
2721 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 42, 255, 1);
2722 expectBufferColor(Rect(2, 0, 3, 1), 122, 0, 0, 255, 1);
2723 }
2724
TEST_P(RenderEngineTest,testDimming_inGammaSpace_withDisplayColorTransform)2725 TEST_P(RenderEngineTest, testDimming_inGammaSpace_withDisplayColorTransform) {
2726 if (!GetParam()->apiSupported()) {
2727 GTEST_SKIP();
2728 }
2729 initializeRenderEngine();
2730
2731 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2732 ui::Dataspace::TRANSFER_GAMMA2_2 |
2733 ui::Dataspace::RANGE_FULL);
2734
2735 const auto displayRect = Rect(3, 1);
2736 const renderengine::DisplaySettings display{
2737 .physicalDisplay = displayRect,
2738 .clip = displayRect,
2739 .outputDataspace = dataspace,
2740 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
2741 .targetLuminanceNits = 1000.f,
2742 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2743 };
2744
2745 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2746 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2747 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2748
2749 const renderengine::LayerSettings greenLayer{
2750 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2751 .source =
2752 renderengine::PixelSource{
2753 .buffer =
2754 renderengine::Buffer{
2755 .buffer = greenBuffer,
2756 .usePremultipliedAlpha = true,
2757 },
2758 },
2759 .alpha = 1.0f,
2760 .sourceDataspace = dataspace,
2761 .whitePointNits = 200.f,
2762 };
2763
2764 const renderengine::LayerSettings redLayer{
2765 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2766 .source =
2767 renderengine::PixelSource{
2768 .buffer =
2769 renderengine::Buffer{
2770 .buffer = redBuffer,
2771 .usePremultipliedAlpha = true,
2772 },
2773 },
2774 .alpha = 1.0f,
2775 .sourceDataspace = dataspace,
2776 // When the white point is not set for a layer, just ignore it and treat it as the same
2777 // as the max layer
2778 .whitePointNits = -1.f,
2779 };
2780
2781 std::vector<renderengine::LayerSettings> layers{greenLayer, redLayer};
2782 invokeDraw(display, layers);
2783
2784 expectBufferColor(Rect(1, 1), 0, 0, 0, 255, 1);
2785 expectBufferColor(Rect(1, 0, 2, 1), 0, 122, 0, 255, 1);
2786 }
2787
TEST_P(RenderEngineTest,testDimming_inGammaSpace_withDisplayColorTransform_deviceHandles)2788 TEST_P(RenderEngineTest, testDimming_inGammaSpace_withDisplayColorTransform_deviceHandles) {
2789 if (!GetParam()->apiSupported()) {
2790 GTEST_SKIP();
2791 }
2792 initializeRenderEngine();
2793
2794 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2795 ui::Dataspace::TRANSFER_GAMMA2_2 |
2796 ui::Dataspace::RANGE_FULL);
2797
2798 const auto displayRect = Rect(3, 1);
2799 const renderengine::DisplaySettings display{
2800 .physicalDisplay = displayRect,
2801 .clip = displayRect,
2802 .outputDataspace = dataspace,
2803 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
2804 .deviceHandlesColorTransform = true,
2805 .targetLuminanceNits = 1000.f,
2806 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2807 };
2808
2809 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2810 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2811 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2812
2813 const renderengine::LayerSettings greenLayer{
2814 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2815 .source =
2816 renderengine::PixelSource{
2817 .buffer =
2818 renderengine::Buffer{
2819 .buffer = greenBuffer,
2820 .usePremultipliedAlpha = true,
2821 },
2822 },
2823 .alpha = 1.0f,
2824 .sourceDataspace = dataspace,
2825 .whitePointNits = 200.f,
2826 };
2827
2828 const renderengine::LayerSettings redLayer{
2829 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2830 .source =
2831 renderengine::PixelSource{
2832 .buffer =
2833 renderengine::Buffer{
2834 .buffer = redBuffer,
2835 .usePremultipliedAlpha = true,
2836 },
2837 },
2838 .alpha = 1.0f,
2839 .sourceDataspace = dataspace,
2840 // When the white point is not set for a layer, just ignore it and treat it as the same
2841 // as the max layer
2842 .whitePointNits = -1.f,
2843 };
2844
2845 std::vector<renderengine::LayerSettings> layers{greenLayer, redLayer};
2846 invokeDraw(display, layers);
2847
2848 expectBufferColor(Rect(1, 1), 0, 122, 0, 255, 1);
2849 expectBufferColor(Rect(1, 0, 2, 1), 122, 0, 0, 255, 1);
2850 }
2851
TEST_P(RenderEngineTest,testDimming_withoutTargetLuminance)2852 TEST_P(RenderEngineTest, testDimming_withoutTargetLuminance) {
2853 if (!GetParam()->apiSupported()) {
2854 GTEST_SKIP();
2855 }
2856 initializeRenderEngine();
2857
2858 const auto displayRect = Rect(2, 1);
2859 const renderengine::DisplaySettings display{
2860 .physicalDisplay = displayRect,
2861 .clip = displayRect,
2862 .outputDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2863 .targetLuminanceNits = -1.f,
2864 };
2865
2866 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2867 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2868
2869 const renderengine::LayerSettings greenLayer{
2870 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2871 .source =
2872 renderengine::PixelSource{
2873 .buffer =
2874 renderengine::Buffer{
2875 .buffer = greenBuffer,
2876 .usePremultipliedAlpha = true,
2877 },
2878 },
2879 .alpha = 1.0f,
2880 .sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2881 .whitePointNits = 200.f,
2882 };
2883
2884 const renderengine::LayerSettings blueLayer{
2885 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2886 .source =
2887 renderengine::PixelSource{
2888 .buffer =
2889 renderengine::Buffer{
2890 .buffer = blueBuffer,
2891 .usePremultipliedAlpha = true,
2892 },
2893 },
2894 .alpha = 1.0f,
2895 .sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2896 .whitePointNits = 1000.f,
2897 };
2898
2899 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer};
2900 invokeDraw(display, layers);
2901
2902 expectBufferColor(Rect(1, 1), 0, 51, 0, 255, 1);
2903 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 255, 255);
2904 }
2905
TEST_P(RenderEngineTest,test_isOpaque)2906 TEST_P(RenderEngineTest, test_isOpaque) {
2907 if (!GetParam()->apiSupported()) {
2908 GTEST_SKIP();
2909 }
2910 initializeRenderEngine();
2911
2912 const auto rect = Rect(0, 0, 1, 1);
2913 const renderengine::DisplaySettings display{
2914 .physicalDisplay = rect,
2915 .clip = rect,
2916 .outputDataspace = ui::Dataspace::DISPLAY_P3,
2917 };
2918
2919 // Create an unpremul buffer that is green with no alpha. Using isOpaque
2920 // should make the green show.
2921 const auto buf = allocateSourceBuffer(1, 1);
2922 {
2923 uint8_t* pixels;
2924 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2925 reinterpret_cast<void**>(&pixels));
2926 pixels[0] = 0;
2927 pixels[1] = 255;
2928 pixels[2] = 0;
2929 pixels[3] = 0;
2930 buf->getBuffer()->unlock();
2931 }
2932
2933 const renderengine::LayerSettings greenLayer{
2934 .geometry.boundaries = rect.toFloatRect(),
2935 .source =
2936 renderengine::PixelSource{
2937 .buffer =
2938 renderengine::Buffer{
2939 .buffer = buf,
2940 // Although the pixels are not
2941 // premultiplied in practice, this
2942 // matches the input we see.
2943 .usePremultipliedAlpha = true,
2944 .isOpaque = true,
2945 },
2946 },
2947 .alpha = 1.0f,
2948 };
2949
2950 std::vector<renderengine::LayerSettings> layers{greenLayer};
2951 invokeDraw(display, layers);
2952
2953 expectBufferColor(rect, 117, 251, 76, 255);
2954 }
2955
TEST_P(RenderEngineTest,test_tonemapPQMatches)2956 TEST_P(RenderEngineTest, test_tonemapPQMatches) {
2957 if (!GetParam()->apiSupported()) {
2958 GTEST_SKIP();
2959 }
2960
2961 initializeRenderEngine();
2962
2963 tonemap(
2964 static_cast<ui::Dataspace>(HAL_DATASPACE_STANDARD_BT2020 |
2965 HAL_DATASPACE_TRANSFER_ST2084 | HAL_DATASPACE_RANGE_FULL),
2966 [](vec3 color) { return EOTF_PQ(color); },
2967 [](vec3 color, float) {
2968 static constexpr float kMaxPQLuminance = 10000.f;
2969 return color * kMaxPQLuminance;
2970 });
2971 }
2972
TEST_P(RenderEngineTest,test_tonemapHLGMatches)2973 TEST_P(RenderEngineTest, test_tonemapHLGMatches) {
2974 if (!GetParam()->apiSupported()) {
2975 GTEST_SKIP();
2976 }
2977
2978 initializeRenderEngine();
2979
2980 tonemap(
2981 static_cast<ui::Dataspace>(HAL_DATASPACE_STANDARD_BT2020 | HAL_DATASPACE_TRANSFER_HLG |
2982 HAL_DATASPACE_RANGE_FULL),
2983 [](vec3 color) { return EOTF_HLG(color); },
2984 [](vec3 color, float currentLuminaceNits) {
2985 static constexpr float kMaxHLGLuminance = 1000.f;
2986 return color * kMaxHLGLuminance;
2987 });
2988 }
2989
TEST_P(RenderEngineTest,r8_behaves_as_mask)2990 TEST_P(RenderEngineTest, r8_behaves_as_mask) {
2991 if (!GetParam()->apiSupported()) {
2992 GTEST_SKIP();
2993 }
2994 initializeRenderEngine();
2995
2996 const auto r8Buffer = allocateR8Buffer(2, 1);
2997 if (!r8Buffer) {
2998 GTEST_SKIP() << "Test is only necessary on devices that support r8";
2999 return;
3000 }
3001 {
3002 uint8_t* pixels;
3003 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
3004 reinterpret_cast<void**>(&pixels));
3005 // This will be drawn on top of a green buffer. We'll verify that 255
3006 // results in keeping the original green and 0 results in black.
3007 pixels[0] = 0;
3008 pixels[1] = 255;
3009 r8Buffer->getBuffer()->unlock();
3010 }
3011
3012 const auto rect = Rect(0, 0, 2, 1);
3013 const renderengine::DisplaySettings display{
3014 .physicalDisplay = rect,
3015 .clip = rect,
3016 .outputDataspace = ui::Dataspace::SRGB,
3017 };
3018
3019 const auto greenBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(0, 255, 0, 255));
3020 const renderengine::LayerSettings greenLayer{
3021 .geometry.boundaries = rect.toFloatRect(),
3022 .source =
3023 renderengine::PixelSource{
3024 .buffer =
3025 renderengine::Buffer{
3026 .buffer = greenBuffer,
3027 },
3028 },
3029 .alpha = 1.0f,
3030 };
3031 const renderengine::LayerSettings r8Layer{
3032 .geometry.boundaries = rect.toFloatRect(),
3033 .source =
3034 renderengine::PixelSource{
3035 .buffer =
3036 renderengine::Buffer{
3037 .buffer = r8Buffer,
3038 },
3039 },
3040 .alpha = 1.0f,
3041 };
3042
3043 std::vector<renderengine::LayerSettings> layers{greenLayer, r8Layer};
3044 invokeDraw(display, layers);
3045
3046 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 255);
3047 expectBufferColor(Rect(1, 0, 2, 1), 0, 255, 0, 255);
3048 }
3049
TEST_P(RenderEngineTest,r8_respects_color_transform)3050 TEST_P(RenderEngineTest, r8_respects_color_transform) {
3051 if (!GetParam()->apiSupported()) {
3052 GTEST_SKIP();
3053 }
3054 initializeRenderEngine();
3055
3056 const auto r8Buffer = allocateR8Buffer(2, 1);
3057 if (!r8Buffer) {
3058 GTEST_SKIP() << "Test is only necessary on devices that support r8";
3059 return;
3060 }
3061 {
3062 uint8_t* pixels;
3063 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
3064 reinterpret_cast<void**>(&pixels));
3065 pixels[0] = 0;
3066 pixels[1] = 255;
3067 r8Buffer->getBuffer()->unlock();
3068 }
3069
3070 const auto rect = Rect(0, 0, 2, 1);
3071 const renderengine::DisplaySettings display{
3072 .physicalDisplay = rect,
3073 .clip = rect,
3074 .outputDataspace = ui::Dataspace::SRGB,
3075 // Verify that the R8 layer respects the color transform when
3076 // deviceHandlesColorTransform is false. This transform converts
3077 // pure red to pure green. That will occur when the R8 buffer is
3078 // 255. When the R8 buffer is 0, it will still change to black, as
3079 // with r8_behaves_as_mask.
3080 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
3081 .deviceHandlesColorTransform = false,
3082 };
3083
3084 const auto redBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(255, 0, 0, 255));
3085 const renderengine::LayerSettings redLayer{
3086 .geometry.boundaries = rect.toFloatRect(),
3087 .source =
3088 renderengine::PixelSource{
3089 .buffer =
3090 renderengine::Buffer{
3091 .buffer = redBuffer,
3092 },
3093 },
3094 .alpha = 1.0f,
3095 };
3096 const renderengine::LayerSettings r8Layer{
3097 .geometry.boundaries = rect.toFloatRect(),
3098 .source =
3099 renderengine::PixelSource{
3100 .buffer =
3101 renderengine::Buffer{
3102 .buffer = r8Buffer,
3103 },
3104 },
3105 .alpha = 1.0f,
3106 };
3107
3108 std::vector<renderengine::LayerSettings> layers{redLayer, r8Layer};
3109 invokeDraw(display, layers);
3110
3111 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 255);
3112 expectBufferColor(Rect(1, 0, 2, 1), 0, 255, 0, 255);
3113 }
3114
TEST_P(RenderEngineTest,r8_respects_color_transform_when_device_handles)3115 TEST_P(RenderEngineTest, r8_respects_color_transform_when_device_handles) {
3116 if (!GetParam()->apiSupported()) {
3117 GTEST_SKIP();
3118 }
3119 initializeRenderEngine();
3120
3121 const auto r8Buffer = allocateR8Buffer(2, 1);
3122 if (!r8Buffer) {
3123 GTEST_SKIP() << "Test is only necessary on devices that support r8";
3124 return;
3125 }
3126 {
3127 uint8_t* pixels;
3128 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
3129 reinterpret_cast<void**>(&pixels));
3130 pixels[0] = 0;
3131 pixels[1] = 255;
3132 r8Buffer->getBuffer()->unlock();
3133 }
3134
3135 const auto rect = Rect(0, 0, 2, 1);
3136 const renderengine::DisplaySettings display{
3137 .physicalDisplay = rect,
3138 .clip = rect,
3139 .outputDataspace = ui::Dataspace::SRGB,
3140 // If deviceHandlesColorTransform is true, pixels where the A8
3141 // buffer is opaque are unaffected. If the colorTransform is
3142 // invertible, pixels where the A8 buffer are transparent have the
3143 // inverse applied to them so that the DPU will convert them back to
3144 // black. Test with an arbitrary, invertible matrix.
3145 .colorTransform = mat4(1, 0, 0, 2,
3146 3, 1, 2, 5,
3147 0, 5, 3, 0,
3148 0, 1, 0, 2),
3149 .deviceHandlesColorTransform = true,
3150 };
3151
3152 const auto redBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(255, 0, 0, 255));
3153 const renderengine::LayerSettings redLayer{
3154 .geometry.boundaries = rect.toFloatRect(),
3155 .source =
3156 renderengine::PixelSource{
3157 .buffer =
3158 renderengine::Buffer{
3159 .buffer = redBuffer,
3160 },
3161 },
3162 .alpha = 1.0f,
3163 };
3164 const renderengine::LayerSettings r8Layer{
3165 .geometry.boundaries = rect.toFloatRect(),
3166 .source =
3167 renderengine::PixelSource{
3168 .buffer =
3169 renderengine::Buffer{
3170 .buffer = r8Buffer,
3171 },
3172 },
3173 .alpha = 1.0f,
3174 };
3175
3176 std::vector<renderengine::LayerSettings> layers{redLayer, r8Layer};
3177 invokeDraw(display, layers);
3178
3179 expectBufferColor(Rect(1, 0, 2, 1), 255, 0, 0, 255); // Still red.
3180 expectBufferColor(Rect(0, 0, 1, 1), 0, 70, 0, 255);
3181 }
3182
TEST_P(RenderEngineTest,localTonemap_preservesFullscreenSdr)3183 TEST_P(RenderEngineTest, localTonemap_preservesFullscreenSdr) {
3184 if (!GetParam()->apiSupported()) {
3185 GTEST_SKIP();
3186 }
3187
3188 initializeRenderEngine();
3189
3190 mBuffer = std::make_shared<
3191 renderengine::impl::
3192 ExternalTexture>(sp<GraphicBuffer>::make(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1,
3193 GRALLOC_USAGE_SW_READ_OFTEN |
3194 GRALLOC_USAGE_SW_WRITE_OFTEN |
3195 GRALLOC_USAGE_HW_RENDER |
3196 GRALLOC_USAGE_HW_TEXTURE,
3197 "output"),
3198 *mRE,
3199 renderengine::impl::ExternalTexture::Usage::READABLE |
3200 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
3201 ASSERT_EQ(0, mBuffer->getBuffer()->initCheck());
3202
3203 const auto whiteBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(51, 51, 51, 255));
3204
3205 const auto rect = Rect(0, 0, 1, 1);
3206 const renderengine::DisplaySettings display{
3207 .physicalDisplay = rect,
3208 .clip = rect,
3209 .outputDataspace = ui::Dataspace::SRGB,
3210 .targetLuminanceNits = 40,
3211 .tonemapStrategy = renderengine::DisplaySettings::TonemapStrategy::Local,
3212 };
3213
3214 const renderengine::LayerSettings whiteLayer{
3215 .geometry.boundaries = rect.toFloatRect(),
3216 .source =
3217 renderengine::PixelSource{
3218 .buffer =
3219 renderengine::Buffer{
3220 .buffer = whiteBuffer,
3221 },
3222 },
3223 .alpha = 1.0f,
3224 .sourceDataspace = ui::Dataspace::V0_SCRGB_LINEAR,
3225 .whitePointNits = 200,
3226 };
3227
3228 std::vector<renderengine::LayerSettings> layers{whiteLayer};
3229 invokeDraw(display, layers);
3230
3231 expectBufferColor(Rect(0, 0, 1, 1), 255, 255, 255, 255);
3232 }
3233
TEST_P(RenderEngineTest,localTonemap_preservesFarawaySdrRegions)3234 TEST_P(RenderEngineTest, localTonemap_preservesFarawaySdrRegions) {
3235 if (!GetParam()->apiSupported()) {
3236 GTEST_SKIP();
3237 }
3238
3239 initializeRenderEngine();
3240
3241 const auto blockWidth = 256;
3242 const auto width = blockWidth * 4;
3243
3244 const auto buffer = allocateSourceBuffer(width, 1);
3245
3246 mBuffer = std::make_shared<
3247 renderengine::impl::
3248 ExternalTexture>(sp<GraphicBuffer>::make(width, 1, HAL_PIXEL_FORMAT_RGBA_8888,
3249 1,
3250 GRALLOC_USAGE_SW_READ_OFTEN |
3251 GRALLOC_USAGE_SW_WRITE_OFTEN |
3252 GRALLOC_USAGE_HW_RENDER |
3253 GRALLOC_USAGE_HW_TEXTURE,
3254 "output"),
3255 *mRE,
3256 renderengine::impl::ExternalTexture::Usage::READABLE |
3257 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
3258
3259 {
3260 uint8_t* pixels;
3261 buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
3262 reinterpret_cast<void**>(&pixels));
3263 uint8_t* dst = pixels;
3264 for (uint32_t i = 0; i < width; i++) {
3265 uint8_t value = 0;
3266 if (i < blockWidth) {
3267 value = 51;
3268 } else if (i >= blockWidth * 3) {
3269 value = 255;
3270 }
3271 dst[0] = value;
3272 dst[1] = value;
3273 dst[2] = value;
3274 dst[3] = 255;
3275 dst += 4;
3276 }
3277 buffer->getBuffer()->unlock();
3278 }
3279
3280 const auto rect = Rect(0, 0, width, 1);
3281 const renderengine::DisplaySettings display{
3282 .physicalDisplay = rect,
3283 .clip = rect,
3284 .outputDataspace = ui::Dataspace::V0_SRGB_LINEAR,
3285 .targetLuminanceNits = 40,
3286 .tonemapStrategy = renderengine::DisplaySettings::TonemapStrategy::Local,
3287 };
3288
3289 const renderengine::LayerSettings whiteLayer{
3290 .geometry.boundaries = rect.toFloatRect(),
3291 .source =
3292 renderengine::PixelSource{
3293 .buffer =
3294 renderengine::Buffer{
3295 .buffer = buffer,
3296 },
3297 },
3298 .alpha = 1.0f,
3299 .sourceDataspace = ui::Dataspace::V0_SCRGB_LINEAR,
3300 .whitePointNits = 200,
3301 };
3302
3303 std::vector<renderengine::LayerSettings> layers{whiteLayer};
3304 invokeDraw(display, layers);
3305
3306 // SDR regions are boosted to preserve SDR detail.
3307 expectBufferColor(Rect(0, 0, blockWidth, 1), 255, 255, 255, 255);
3308 expectBufferColor(Rect(blockWidth, 0, blockWidth * 2, 1), 0, 0, 0, 255);
3309 expectBufferColor(Rect(blockWidth * 2, 0, blockWidth * 3, 1), 0, 0, 0, 255);
3310 expectBufferColor(Rect(blockWidth * 3, 0, blockWidth * 4, 1), 255, 255, 255, 255);
3311 }
3312
TEST_P(RenderEngineTest,localTonemap_tonemapsNearbySdrRegions)3313 TEST_P(RenderEngineTest, localTonemap_tonemapsNearbySdrRegions) {
3314 if (!GetParam()->apiSupported()) {
3315 GTEST_SKIP();
3316 }
3317
3318 initializeRenderEngine();
3319
3320 const auto blockWidth = 2;
3321 const auto width = blockWidth * 2;
3322
3323 mBuffer = std::make_shared<
3324 renderengine::impl::
3325 ExternalTexture>(sp<GraphicBuffer>::make(width, 1, HAL_PIXEL_FORMAT_RGBA_8888,
3326 1,
3327 GRALLOC_USAGE_SW_READ_OFTEN |
3328 GRALLOC_USAGE_SW_WRITE_OFTEN |
3329 GRALLOC_USAGE_HW_RENDER |
3330 GRALLOC_USAGE_HW_TEXTURE,
3331 "output"),
3332 *mRE,
3333 renderengine::impl::ExternalTexture::Usage::READABLE |
3334 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
3335
3336 const auto buffer = allocateSourceBuffer(width, 1);
3337
3338 {
3339 uint8_t* pixels;
3340 buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
3341 reinterpret_cast<void**>(&pixels));
3342 uint8_t* dst = pixels;
3343 for (uint32_t i = 0; i < width; i++) {
3344 uint8_t value = 0;
3345 if (i < blockWidth) {
3346 value = 51;
3347 } else if (i >= blockWidth) {
3348 value = 255;
3349 }
3350 dst[0] = value;
3351 dst[1] = value;
3352 dst[2] = value;
3353 dst[3] = 255;
3354 dst += 4;
3355 }
3356 buffer->getBuffer()->unlock();
3357 }
3358
3359 const auto rect = Rect(0, 0, width, 1);
3360 const renderengine::DisplaySettings display{
3361 .physicalDisplay = rect,
3362 .clip = rect,
3363 .outputDataspace = ui::Dataspace::V0_SRGB_LINEAR,
3364 .targetLuminanceNits = 40,
3365 .tonemapStrategy = renderengine::DisplaySettings::TonemapStrategy::Local,
3366 };
3367
3368 const renderengine::LayerSettings whiteLayer{
3369 .geometry.boundaries = rect.toFloatRect(),
3370 .source =
3371 renderengine::PixelSource{
3372 .buffer =
3373 renderengine::Buffer{
3374 .buffer = buffer,
3375 },
3376 },
3377 .alpha = 1.0f,
3378 .sourceDataspace = ui::Dataspace::V0_SCRGB_LINEAR,
3379 .whitePointNits = 200,
3380 };
3381
3382 std::vector<renderengine::LayerSettings> layers{whiteLayer};
3383 invokeDraw(display, layers);
3384
3385 // SDR regions remain "dimmed", but preserve detail with a roll-off curve.
3386 expectBufferColor(Rect(0, 0, blockWidth, 1), 132, 132, 132, 255, 2);
3387 // HDR regions are not dimmed.
3388 expectBufferColor(Rect(blockWidth, 0, blockWidth * 2, 1), 255, 255, 255, 255);
3389 }
3390
TEST_P(RenderEngineTest,primeShaderCache)3391 TEST_P(RenderEngineTest, primeShaderCache) {
3392 // TODO: b/331447071 - Fix in Graphite and re-enable.
3393 if (GetParam()->skiaBackend() == renderengine::RenderEngine::SkiaBackend::GRAPHITE) {
3394 GTEST_SKIP();
3395 }
3396
3397 if (!GetParam()->apiSupported()) {
3398 GTEST_SKIP();
3399 }
3400 initializeRenderEngine();
3401
3402 PrimeCacheConfig config;
3403 config.cacheUltraHDR = false;
3404 auto fut = mRE->primeCache(config);
3405 if (fut.valid()) {
3406 fut.wait();
3407 }
3408
3409 static constexpr int kMinimumExpectedShadersCompiled = 60;
3410 ASSERT_GT(static_cast<skia::SkiaGLRenderEngine*>(mRE.get())->reportShadersCompiled(),
3411 kMinimumExpectedShadersCompiled);
3412 }
3413 } // namespace renderengine
3414 } // namespace android
3415
3416 // TODO(b/129481165): remove the #pragma below and fix conversion issues
3417 #pragma clang diagnostic pop // ignored "-Wconversion -Wextra"
3418