xref: /aosp_15_r20/frameworks/native/libs/renderengine/tests/RenderEngineTest.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
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