1 /*
2  * Copyright 2021 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 #include <common/include/common/test/FlagUtils.h>
18 #include "com_android_graphics_surfaceflinger_flags.h"
19 
20 #include <compositionengine/impl/OutputCompositionState.h>
21 #include <compositionengine/impl/planner/CachedSet.h>
22 #include <compositionengine/impl/planner/Flattener.h>
23 #include <compositionengine/impl/planner/LayerState.h>
24 #include <compositionengine/mock/LayerFE.h>
25 #include <compositionengine/mock/OutputLayer.h>
26 #include <gtest/gtest.h>
27 #include <renderengine/ExternalTexture.h>
28 #include <renderengine/LayerSettings.h>
29 #include <renderengine/impl/ExternalTexture.h>
30 #include <renderengine/mock/RenderEngine.h>
31 #include <chrono>
32 
33 namespace android::compositionengine {
34 using namespace std::chrono_literals;
35 using impl::planner::CachedSet;
36 using impl::planner::Flattener;
37 using impl::planner::LayerState;
38 using impl::planner::NonBufferHash;
39 
40 using testing::_;
41 using testing::ByMove;
42 using testing::ByRef;
43 using testing::DoAll;
44 using testing::Invoke;
45 using testing::Return;
46 using testing::ReturnRef;
47 using testing::Sequence;
48 using testing::SetArgPointee;
49 
50 namespace {
51 
52 class TestableFlattener : public Flattener {
53 public:
TestableFlattener(renderengine::RenderEngine & renderEngine,const Tunables & tunables)54     TestableFlattener(renderengine::RenderEngine& renderEngine, const Tunables& tunables)
55           : Flattener(renderEngine, tunables) {}
getNewCachedSetForTesting() const56     const std::optional<CachedSet>& getNewCachedSetForTesting() const { return mNewCachedSet; }
57 };
58 
59 class FlattenerTest : public testing::Test {
60 public:
FlattenerTest()61     FlattenerTest()
62           : FlattenerTest(Flattener::Tunables{
63                     .mActiveLayerTimeout = 100ms,
64                     .mRenderScheduling = std::nullopt,
65                     .mEnableHolePunch = true,
66             }) {}
67     void SetUp() override;
68 
69 protected:
FlattenerTest(const Flattener::Tunables & tunables)70     FlattenerTest(const Flattener::Tunables& tunables)
71           : mFlattener(std::make_unique<TestableFlattener>(mRenderEngine, tunables)) {}
72     void initializeOverrideBuffer(const std::vector<const LayerState*>& layers);
73     void initializeFlattener(const std::vector<const LayerState*>& layers);
74     void expectAllLayersFlattened(const std::vector<const LayerState*>& layers);
75 
76     // mRenderEngine is held as a reference in mFlattener, so explicitly destroy mFlattener first.
77     renderengine::mock::RenderEngine mRenderEngine;
78     std::unique_ptr<TestableFlattener> mFlattener;
79 
80     const std::chrono::steady_clock::time_point kStartTime = std::chrono::steady_clock::now();
81     std::chrono::steady_clock::time_point mTime = kStartTime;
82 
83     struct TestLayer {
84         std::string name;
85         mock::OutputLayer outputLayer;
86         impl::OutputLayerCompositionState outputLayerCompositionState;
87         // LayerFE inherits from RefBase and must be held by an sp<>
88         sp<mock::LayerFE> layerFE;
89         LayerFECompositionState layerFECompositionState;
90 
91         std::unique_ptr<LayerState> layerState;
92     };
93 
94     static constexpr size_t kNumLayers = 5;
95     std::vector<std::unique_ptr<TestLayer>> mTestLayers;
96     impl::OutputCompositionState mOutputState;
97 };
98 
SetUp()99 void FlattenerTest::SetUp() {
100     mFlattener->setDisplaySize({1, 1});
101     for (size_t i = 0; i < kNumLayers; i++) {
102         auto testLayer = std::make_unique<TestLayer>();
103         auto pos = static_cast<int32_t>(i);
104         std::stringstream ss;
105         ss << "testLayer" << i;
106         testLayer->name = ss.str();
107 
108         testLayer->outputLayerCompositionState.displayFrame = Rect(pos, pos, pos + 1, pos + 1);
109         testLayer->outputLayerCompositionState.visibleRegion =
110                 Region(Rect(pos + 1, pos + 1, pos + 2, pos + 2));
111 
112         const auto kUsageFlags =
113                 static_cast<uint64_t>(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
114                                       GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE);
115         testLayer->layerFECompositionState.buffer =
116                 sp<GraphicBuffer>::make(100u, 100u, HAL_PIXEL_FORMAT_RGBA_8888, 1u, kUsageFlags,
117                                         "output");
118 
119         testLayer->layerFE = sp<mock::LayerFE>::make();
120 
121         EXPECT_CALL(*testLayer->layerFE, getSequence)
122                 .WillRepeatedly(Return(static_cast<int32_t>(i)));
123         EXPECT_CALL(*testLayer->layerFE, getDebugName)
124                 .WillRepeatedly(Return(testLayer->name.c_str()));
125         EXPECT_CALL(*testLayer->layerFE, getCompositionState)
126                 .WillRepeatedly(Return(&testLayer->layerFECompositionState));
127 
128         std::optional<LayerFE::LayerSettings> clientComposition;
129         clientComposition.emplace();
130 
131         EXPECT_CALL(*testLayer->layerFE, prepareClientComposition)
132                 .WillRepeatedly(Return(clientComposition));
133         EXPECT_CALL(testLayer->outputLayer, getLayerFE)
134                 .WillRepeatedly(ReturnRef(*testLayer->layerFE));
135         EXPECT_CALL(testLayer->outputLayer, getState)
136                 .WillRepeatedly(ReturnRef(testLayer->outputLayerCompositionState));
137         EXPECT_CALL(testLayer->outputLayer, editState)
138                 .WillRepeatedly(ReturnRef(testLayer->outputLayerCompositionState));
139 
140         testLayer->layerState = std::make_unique<LayerState>(&testLayer->outputLayer);
141         testLayer->layerState->incrementFramesSinceBufferUpdate();
142 
143         mTestLayers.emplace_back(std::move(testLayer));
144 
145         // set up minimium params needed for rendering
146         mOutputState.dataspace = ui::Dataspace::SRGB;
147         mOutputState.framebufferSpace = ProjectionSpace(ui::Size(10, 20), Rect(10, 5));
148         mOutputState.framebufferSpace.setOrientation(ui::ROTATION_90);
149     }
150 }
151 
initializeOverrideBuffer(const std::vector<const LayerState * > & layers)152 void FlattenerTest::initializeOverrideBuffer(const std::vector<const LayerState*>& layers) {
153     for (const auto layer : layers) {
154         layer->getOutputLayer()->editState().overrideInfo = {};
155     }
156 }
157 
initializeFlattener(const std::vector<const LayerState * > & layers)158 void FlattenerTest::initializeFlattener(const std::vector<const LayerState*>& layers) {
159     // layer stack is unknown, reset current geomentry
160     initializeOverrideBuffer(layers);
161     EXPECT_EQ(getNonBufferHash(layers),
162               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
163     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
164 
165     // same geometry, update the internal layer stack
166     initializeOverrideBuffer(layers);
167     EXPECT_EQ(getNonBufferHash(layers),
168               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
169     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
170 }
171 
expectAllLayersFlattened(const std::vector<const LayerState * > & layers)172 void FlattenerTest::expectAllLayersFlattened(const std::vector<const LayerState*>& layers) {
173     // layers would be flattened but the buffer would not be overridden
174     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _))
175             .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
176 
177     initializeOverrideBuffer(layers);
178     EXPECT_EQ(getNonBufferHash(layers),
179               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
180     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
181 
182     for (const auto layer : layers) {
183         EXPECT_EQ(nullptr, layer->getOutputLayer()->getState().overrideInfo.buffer);
184     }
185 
186     // the new flattened layer is replaced
187     initializeOverrideBuffer(layers);
188     EXPECT_NE(getNonBufferHash(layers),
189               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
190     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
191 
192     const auto buffer = layers[0]->getOutputLayer()->getState().overrideInfo.buffer;
193     EXPECT_NE(nullptr, buffer);
194     for (const auto layer : layers) {
195         EXPECT_EQ(buffer, layer->getOutputLayer()->getState().overrideInfo.buffer);
196     }
197 }
198 
TEST_F(FlattenerTest,flattenLayers_NewLayerStack)199 TEST_F(FlattenerTest, flattenLayers_NewLayerStack) {
200     auto& layerState1 = mTestLayers[0]->layerState;
201     auto& layerState2 = mTestLayers[1]->layerState;
202 
203     const std::vector<const LayerState*> layers = {
204             layerState1.get(),
205             layerState2.get(),
206     };
207     initializeFlattener(layers);
208 }
209 
TEST_F(FlattenerTest,flattenLayers_ActiveLayersAreNotFlattened)210 TEST_F(FlattenerTest, flattenLayers_ActiveLayersAreNotFlattened) {
211     auto& layerState1 = mTestLayers[0]->layerState;
212     auto& layerState2 = mTestLayers[1]->layerState;
213 
214     const std::vector<const LayerState*> layers = {
215             layerState1.get(),
216             layerState2.get(),
217     };
218 
219     initializeFlattener(layers);
220 
221     // layers cannot be flattened yet, since they are still active
222     initializeOverrideBuffer(layers);
223     EXPECT_EQ(getNonBufferHash(layers),
224               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
225     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
226 }
227 
TEST_F(FlattenerTest,flattenLayers_ActiveLayersWithLowFpsAreFlattened)228 TEST_F(FlattenerTest, flattenLayers_ActiveLayersWithLowFpsAreFlattened) {
229     auto& layerState1 = mTestLayers[0]->layerState;
230     auto& layerState2 = mTestLayers[1]->layerState;
231 
232     const std::vector<const LayerState*> layers = {
233             layerState1.get(),
234             layerState2.get(),
235     };
236 
237     initializeFlattener(layers);
238 
239     mTestLayers[0]->layerFECompositionState.fps = Flattener::kFpsActiveThreshold / 2;
240     mTestLayers[1]->layerFECompositionState.fps = Flattener::kFpsActiveThreshold;
241 
242     expectAllLayersFlattened(layers);
243 }
244 
TEST_F(FlattenerTest,unflattenLayers_onlySourceCropMoved)245 TEST_F(FlattenerTest, unflattenLayers_onlySourceCropMoved) {
246     SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::
247                               cache_when_source_crop_layer_only_moved,
248                       true);
249 
250     auto& layerState1 = mTestLayers[0]->layerState;
251     auto& layerState2 = mTestLayers[1]->layerState;
252 
253     const std::vector<const LayerState*> layers = {
254             layerState1.get(),
255             layerState2.get(),
256     };
257 
258     initializeFlattener(layers);
259 
260     mTestLayers[0]->outputLayerCompositionState.sourceCrop = FloatRect{0.f, 0.f, 100.f, 100.f};
261     mTestLayers[1]->outputLayerCompositionState.sourceCrop = FloatRect{8.f, 16.f, 108.f, 116.f};
262 
263     // only source crop is moved, so no flatten
264     EXPECT_EQ(getNonBufferHash(layers),
265               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
266     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
267 }
268 
TEST_F(FlattenerTest,flattenLayers_basicFlatten)269 TEST_F(FlattenerTest, flattenLayers_basicFlatten) {
270     auto& layerState1 = mTestLayers[0]->layerState;
271     auto& layerState2 = mTestLayers[1]->layerState;
272     auto& layerState3 = mTestLayers[2]->layerState;
273 
274     const std::vector<const LayerState*> layers = {
275             layerState1.get(),
276             layerState2.get(),
277             layerState3.get(),
278     };
279 
280     initializeFlattener(layers);
281 
282     // make all layers inactive
283     mTime += 200ms;
284     expectAllLayersFlattened(layers);
285 }
286 
TEST_F(FlattenerTest,flattenLayers_FlattenedLayersStayFlattenWhenNoUpdate)287 TEST_F(FlattenerTest, flattenLayers_FlattenedLayersStayFlattenWhenNoUpdate) {
288     auto& layerState1 = mTestLayers[0]->layerState;
289     const auto& overrideBuffer1 = layerState1->getOutputLayer()->getState().overrideInfo.buffer;
290 
291     auto& layerState2 = mTestLayers[1]->layerState;
292     const auto& overrideBuffer2 = layerState2->getOutputLayer()->getState().overrideInfo.buffer;
293 
294     auto& layerState3 = mTestLayers[2]->layerState;
295     const auto& overrideBuffer3 = layerState3->getOutputLayer()->getState().overrideInfo.buffer;
296 
297     const std::vector<const LayerState*> layers = {
298             layerState1.get(),
299             layerState2.get(),
300             layerState3.get(),
301     };
302 
303     initializeFlattener(layers);
304 
305     // make all layers inactive
306     mTime += 200ms;
307     expectAllLayersFlattened(layers);
308 
309     initializeOverrideBuffer(layers);
310     EXPECT_NE(getNonBufferHash(layers),
311               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
312     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
313 
314     EXPECT_NE(nullptr, overrideBuffer1);
315     EXPECT_EQ(overrideBuffer1, overrideBuffer2);
316     EXPECT_EQ(overrideBuffer2, overrideBuffer3);
317 }
318 
TEST_F(FlattenerTest,flattenLayers_FlattenedLayersSetsProjectionSpace)319 TEST_F(FlattenerTest, flattenLayers_FlattenedLayersSetsProjectionSpace) {
320     auto& layerState1 = mTestLayers[0]->layerState;
321     const auto& overrideDisplaySpace =
322             layerState1->getOutputLayer()->getState().overrideInfo.displaySpace;
323 
324     auto& layerState2 = mTestLayers[1]->layerState;
325 
326     const std::vector<const LayerState*> layers = {
327             layerState1.get(),
328             layerState2.get(),
329     };
330 
331     initializeFlattener(layers);
332 
333     // make all layers inactive
334     mTime += 200ms;
335     expectAllLayersFlattened(layers);
336 
337     EXPECT_EQ(overrideDisplaySpace, mOutputState.framebufferSpace);
338 }
339 
TEST_F(FlattenerTest,flattenLayers_FlattenedLayersSetsDamageRegions)340 TEST_F(FlattenerTest, flattenLayers_FlattenedLayersSetsDamageRegions) {
341     auto& layerState1 = mTestLayers[0]->layerState;
342     const auto& overrideDamageRegion =
343             layerState1->getOutputLayer()->getState().overrideInfo.damageRegion;
344 
345     auto& layerState2 = mTestLayers[1]->layerState;
346 
347     const std::vector<const LayerState*> layers = {
348             layerState1.get(),
349             layerState2.get(),
350     };
351 
352     initializeFlattener(layers);
353 
354     // make all layers inactive
355     mTime += 200ms;
356     expectAllLayersFlattened(layers);
357     EXPECT_TRUE(overrideDamageRegion.isRect() &&
358                 overrideDamageRegion.bounds() == Rect::INVALID_RECT);
359 
360     initializeOverrideBuffer(layers);
361     EXPECT_NE(getNonBufferHash(layers),
362               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
363     EXPECT_TRUE(overrideDamageRegion.isRect() && overrideDamageRegion.bounds() == Rect::EMPTY_RECT);
364 }
365 
TEST_F(FlattenerTest,flattenLayers_FlattenedLayersSetsVisibleRegion)366 TEST_F(FlattenerTest, flattenLayers_FlattenedLayersSetsVisibleRegion) {
367     auto& layerState1 = mTestLayers[0]->layerState;
368     const auto& overrideVisibleRegion =
369             layerState1->getOutputLayer()->getState().overrideInfo.visibleRegion;
370 
371     auto& layerState2 = mTestLayers[1]->layerState;
372 
373     const std::vector<const LayerState*> layers = {
374             layerState1.get(),
375             layerState2.get(),
376     };
377 
378     initializeFlattener(layers);
379 
380     // make all layers inactive
381     mTime += 200ms;
382     expectAllLayersFlattened(layers);
383     Region expectedRegion;
384     expectedRegion.orSelf(Rect(1, 1, 2, 2));
385     expectedRegion.orSelf(Rect(2, 2, 3, 3));
386     EXPECT_TRUE(overrideVisibleRegion.hasSameRects(expectedRegion));
387 }
388 
TEST_F(FlattenerTest,flattenLayers_addLayerToFlattenedCauseReset)389 TEST_F(FlattenerTest, flattenLayers_addLayerToFlattenedCauseReset) {
390     auto& layerState1 = mTestLayers[0]->layerState;
391     const auto& overrideBuffer1 = layerState1->getOutputLayer()->getState().overrideInfo.buffer;
392 
393     auto& layerState2 = mTestLayers[1]->layerState;
394     const auto& overrideBuffer2 = layerState2->getOutputLayer()->getState().overrideInfo.buffer;
395 
396     auto& layerState3 = mTestLayers[2]->layerState;
397     const auto& overrideBuffer3 = layerState3->getOutputLayer()->getState().overrideInfo.buffer;
398 
399     std::vector<const LayerState*> layers = {
400             layerState1.get(),
401             layerState2.get(),
402     };
403 
404     initializeFlattener(layers);
405     // make all layers inactive
406     mTime += 200ms;
407 
408     initializeOverrideBuffer(layers);
409     expectAllLayersFlattened(layers);
410 
411     // add a new layer to the stack, this will cause all the flatenner to reset
412     layers.push_back(layerState3.get());
413 
414     initializeOverrideBuffer(layers);
415     EXPECT_EQ(getNonBufferHash(layers),
416               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
417     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
418 
419     EXPECT_EQ(nullptr, overrideBuffer1);
420     EXPECT_EQ(nullptr, overrideBuffer2);
421     EXPECT_EQ(nullptr, overrideBuffer3);
422 }
423 
TEST_F(FlattenerTest,flattenLayers_BufferUpdateToFlatten)424 TEST_F(FlattenerTest, flattenLayers_BufferUpdateToFlatten) {
425     auto& layerState1 = mTestLayers[0]->layerState;
426     const auto& overrideBuffer1 = layerState1->getOutputLayer()->getState().overrideInfo.buffer;
427 
428     auto& layerState2 = mTestLayers[1]->layerState;
429     const auto& overrideBuffer2 = layerState2->getOutputLayer()->getState().overrideInfo.buffer;
430 
431     auto& layerState3 = mTestLayers[2]->layerState;
432     const auto& overrideBuffer3 = layerState3->getOutputLayer()->getState().overrideInfo.buffer;
433 
434     const std::vector<const LayerState*> layers = {
435             layerState1.get(),
436             layerState2.get(),
437             layerState3.get(),
438     };
439 
440     initializeFlattener(layers);
441 
442     // make all layers inactive
443     mTime += 200ms;
444     expectAllLayersFlattened(layers);
445 
446     // Layer 1 posted a buffer update, layers would be decomposed, and a new drawFrame would be
447     // caleed for Layer2 and Layer3
448     layerState1->resetFramesSinceBufferUpdate();
449 
450     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _))
451             .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
452     initializeOverrideBuffer(layers);
453     EXPECT_EQ(getNonBufferHash(layers),
454               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
455     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
456 
457     EXPECT_EQ(nullptr, overrideBuffer1);
458     EXPECT_EQ(nullptr, overrideBuffer2);
459     EXPECT_EQ(nullptr, overrideBuffer3);
460 
461     initializeOverrideBuffer(layers);
462     EXPECT_NE(getNonBufferHash(layers),
463               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
464     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
465 
466     EXPECT_EQ(nullptr, overrideBuffer1);
467     EXPECT_NE(nullptr, overrideBuffer2);
468     EXPECT_EQ(overrideBuffer2, overrideBuffer3);
469 
470     layerState1->incrementFramesSinceBufferUpdate();
471     mTime += 200ms;
472 
473     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _))
474             .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
475     initializeOverrideBuffer(layers);
476     EXPECT_NE(getNonBufferHash(layers),
477               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
478     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
479 
480     EXPECT_EQ(nullptr, overrideBuffer1);
481     EXPECT_NE(nullptr, overrideBuffer2);
482     EXPECT_EQ(overrideBuffer2, overrideBuffer3);
483 
484     initializeOverrideBuffer(layers);
485     EXPECT_NE(getNonBufferHash(layers),
486               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
487     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
488 
489     EXPECT_NE(nullptr, overrideBuffer1);
490     EXPECT_EQ(overrideBuffer1, overrideBuffer2);
491     EXPECT_EQ(overrideBuffer2, overrideBuffer3);
492 }
493 
TEST_F(FlattenerTest,flattenLayers_BufferUpdateForMiddleLayer)494 TEST_F(FlattenerTest, flattenLayers_BufferUpdateForMiddleLayer) {
495     auto& layerState1 = mTestLayers[0]->layerState;
496     const auto& overrideBuffer1 = layerState1->getOutputLayer()->getState().overrideInfo.buffer;
497 
498     auto& layerState2 = mTestLayers[1]->layerState;
499     const auto& overrideBuffer2 = layerState2->getOutputLayer()->getState().overrideInfo.buffer;
500 
501     auto& layerState3 = mTestLayers[2]->layerState;
502     const auto& overrideBuffer3 = layerState3->getOutputLayer()->getState().overrideInfo.buffer;
503 
504     auto& layerState4 = mTestLayers[3]->layerState;
505     const auto& overrideBuffer4 = layerState4->getOutputLayer()->getState().overrideInfo.buffer;
506 
507     auto& layerState5 = mTestLayers[4]->layerState;
508     const auto& overrideBuffer5 = layerState5->getOutputLayer()->getState().overrideInfo.buffer;
509 
510     const std::vector<const LayerState*> layers = {
511             layerState1.get(), layerState2.get(), layerState3.get(),
512             layerState4.get(), layerState5.get(),
513     };
514 
515     initializeFlattener(layers);
516 
517     // make all layers inactive
518     mTime += 200ms;
519     expectAllLayersFlattened(layers);
520 
521     // Layer 3 posted a buffer update, layers would be decomposed, and a new drawFrame would be
522     // called for Layer1 and Layer2
523     layerState3->resetFramesSinceBufferUpdate();
524 
525     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _))
526             .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
527     initializeOverrideBuffer(layers);
528     EXPECT_EQ(getNonBufferHash(layers),
529               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
530     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
531 
532     EXPECT_EQ(nullptr, overrideBuffer1);
533     EXPECT_EQ(nullptr, overrideBuffer2);
534     EXPECT_EQ(nullptr, overrideBuffer3);
535     EXPECT_EQ(nullptr, overrideBuffer4);
536     EXPECT_EQ(nullptr, overrideBuffer5);
537 
538     // Layers 1 and 2 will be flattened a new drawFrame would be called for Layer4 and Layer5
539     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _))
540             .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
541     initializeOverrideBuffer(layers);
542     EXPECT_NE(getNonBufferHash(layers),
543               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
544     mOutputState.framebufferSpace.setOrientation(ui::ROTATION_90);
545     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
546 
547     EXPECT_NE(nullptr, overrideBuffer1);
548     EXPECT_EQ(overrideBuffer1, overrideBuffer2);
549     EXPECT_EQ(nullptr, overrideBuffer3);
550     EXPECT_EQ(nullptr, overrideBuffer4);
551     EXPECT_EQ(nullptr, overrideBuffer5);
552 
553     // Layers 4 and 5 will be flattened
554     initializeOverrideBuffer(layers);
555     EXPECT_NE(getNonBufferHash(layers),
556               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
557     mOutputState.framebufferSpace.setOrientation(ui::ROTATION_180);
558     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
559 
560     EXPECT_NE(nullptr, overrideBuffer1);
561     EXPECT_EQ(overrideBuffer1, overrideBuffer2);
562     EXPECT_EQ(nullptr, overrideBuffer3);
563     EXPECT_NE(nullptr, overrideBuffer4);
564     EXPECT_EQ(overrideBuffer4, overrideBuffer5);
565 
566     layerState3->incrementFramesSinceBufferUpdate();
567     mTime += 200ms;
568     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _))
569             .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
570     initializeOverrideBuffer(layers);
571     EXPECT_NE(getNonBufferHash(layers),
572               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
573     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
574 
575     EXPECT_NE(nullptr, overrideBuffer1);
576     EXPECT_EQ(overrideBuffer1, overrideBuffer2);
577     EXPECT_EQ(nullptr, overrideBuffer3);
578     EXPECT_NE(nullptr, overrideBuffer4);
579     EXPECT_EQ(overrideBuffer4, overrideBuffer5);
580 
581     initializeOverrideBuffer(layers);
582     EXPECT_NE(getNonBufferHash(layers),
583               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
584     mOutputState.framebufferSpace.setOrientation(ui::ROTATION_270);
585     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
586 
587     EXPECT_NE(nullptr, overrideBuffer1);
588     EXPECT_EQ(overrideBuffer1, overrideBuffer2);
589     EXPECT_EQ(overrideBuffer2, overrideBuffer3);
590     EXPECT_EQ(overrideBuffer3, overrideBuffer4);
591     EXPECT_EQ(overrideBuffer4, overrideBuffer5);
592 }
593 
594 // Tests for a PIP
TEST_F(FlattenerTest,flattenLayers_pipRequiresRoundedCorners)595 TEST_F(FlattenerTest, flattenLayers_pipRequiresRoundedCorners) {
596     auto& layerState1 = mTestLayers[0]->layerState;
597     const auto& overrideBuffer1 = layerState1->getOutputLayer()->getState().overrideInfo.buffer;
598 
599     auto& layerState2 = mTestLayers[1]->layerState;
600     const auto& overrideBuffer2 = layerState2->getOutputLayer()->getState().overrideInfo.buffer;
601 
602     auto& layerState3 = mTestLayers[2]->layerState;
603     const auto& overrideBuffer3 = layerState3->getOutputLayer()->getState().overrideInfo.buffer;
604 
605     const std::vector<const LayerState*> layers = {
606             layerState1.get(),
607             layerState2.get(),
608             layerState3.get(),
609     };
610 
611     initializeFlattener(layers);
612 
613     // 3 has a buffer update, so it will not be merged, but it has no round
614     // corners, so it is not a PIP.
615     mTime += 200ms;
616     layerState3->resetFramesSinceBufferUpdate();
617 
618     initializeOverrideBuffer(layers);
619     EXPECT_EQ(getNonBufferHash(layers),
620               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
621 
622     // This will render a CachedSet.
623     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _))
624             .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
625     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
626 
627     // We've rendered a CachedSet, but we haven't merged it in.
628     EXPECT_EQ(nullptr, overrideBuffer1);
629     EXPECT_EQ(nullptr, overrideBuffer2);
630     EXPECT_EQ(nullptr, overrideBuffer3);
631 
632     // This time we merge the CachedSet in, so we have a new hash, and we should
633     // only have two sets.
634     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _)).Times(0);
635     initializeOverrideBuffer(layers);
636     EXPECT_NE(getNonBufferHash(layers),
637               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
638     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
639 
640     EXPECT_NE(nullptr, overrideBuffer1);
641     EXPECT_EQ(overrideBuffer1, overrideBuffer2);
642     EXPECT_EQ(nullptr, overrideBuffer3);
643 }
644 
TEST_F(FlattenerTest,flattenLayers_pip)645 TEST_F(FlattenerTest, flattenLayers_pip) {
646     mTestLayers[0]->outputLayerCompositionState.displayFrame = Rect(0, 0, 5, 5);
647     auto& layerState1 = mTestLayers[0]->layerState;
648     const auto& overrideBuffer1 = layerState1->getOutputLayer()->getState().overrideInfo.buffer;
649 
650     auto& layerState2 = mTestLayers[1]->layerState;
651     const auto& overrideBuffer2 = layerState2->getOutputLayer()->getState().overrideInfo.buffer;
652 
653     auto& layerState3 = mTestLayers[2]->layerState;
654     const auto& overrideBuffer3 = layerState3->getOutputLayer()->getState().overrideInfo.buffer;
655     mTestLayers[2]->layerFECompositionState.blendMode = hal::BlendMode::NONE;
656 
657     EXPECT_CALL(*mTestLayers[2]->layerFE, hasRoundedCorners()).WillRepeatedly(Return(true));
658 
659     std::optional<LayerFE::LayerSettings> clientComposition;
660     clientComposition.emplace();
661     clientComposition->source.buffer.buffer = std::make_shared<
662             renderengine::impl::ExternalTexture>(mTestLayers[2]->layerFECompositionState.buffer,
663                                                  mRenderEngine,
664                                                  renderengine::impl::ExternalTexture::Usage::
665                                                          READABLE);
666     EXPECT_CALL(*mTestLayers[2]->layerFE, prepareClientComposition(_))
667             .WillOnce(Return(clientComposition));
668 
669     const std::vector<const LayerState*> layers = {
670             layerState1.get(),
671             layerState2.get(),
672             layerState3.get(),
673     };
674 
675     initializeFlattener(layers);
676 
677     // 3 has a buffer update, so it will not be merged, and it has round
678     // corners, so it is a PIP.
679     mTime += 200ms;
680     layerState3->resetFramesSinceBufferUpdate();
681 
682     initializeOverrideBuffer(layers);
683     EXPECT_EQ(getNonBufferHash(layers),
684               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
685 
686     // This will render a CachedSet.
687     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _))
688             .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
689     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
690 
691     // We've rendered a CachedSet, but we haven't merged it in.
692     EXPECT_EQ(nullptr, overrideBuffer1);
693     EXPECT_EQ(nullptr, overrideBuffer2);
694     EXPECT_EQ(nullptr, overrideBuffer3);
695 
696     // This time we merge the CachedSet in, so we have a new hash, and we should
697     // only have two sets.
698     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _)).Times(0);
699     initializeOverrideBuffer(layers);
700     EXPECT_NE(getNonBufferHash(layers),
701               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
702     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
703 
704     EXPECT_NE(nullptr, overrideBuffer1);
705     EXPECT_EQ(overrideBuffer1, overrideBuffer2);
706     EXPECT_EQ(nullptr, overrideBuffer3);
707 
708     const auto* peekThroughLayer1 =
709             layerState1->getOutputLayer()->getState().overrideInfo.peekThroughLayer;
710     const auto* peekThroughLayer2 =
711             layerState2->getOutputLayer()->getState().overrideInfo.peekThroughLayer;
712     EXPECT_EQ(&mTestLayers[2]->outputLayer, peekThroughLayer1);
713     EXPECT_EQ(peekThroughLayer1, peekThroughLayer2);
714 }
715 
716 // A test that verifies the hole puch optimization can be done on a single layer.
TEST_F(FlattenerTest,flattenLayers_holePunchSingleLayer)717 TEST_F(FlattenerTest, flattenLayers_holePunchSingleLayer) {
718     mTestLayers[0]->outputLayerCompositionState.displayFrame = Rect(0, 0, 5, 5);
719 
720     // An opaque static background
721     auto& layerState0 = mTestLayers[0]->layerState;
722     const auto& overrideBuffer0 = layerState0->getOutputLayer()->getState().overrideInfo.buffer;
723 
724     // a rounded updating layer
725     auto& layerState1 = mTestLayers[1]->layerState;
726     const auto& overrideBuffer1 = layerState1->getOutputLayer()->getState().overrideInfo.buffer;
727     mTestLayers[1]->layerFECompositionState.blendMode = hal::BlendMode::NONE;
728 
729     EXPECT_CALL(*mTestLayers[1]->layerFE, hasRoundedCorners()).WillRepeatedly(Return(true));
730 
731     std::optional<LayerFE::LayerSettings> clientComposition;
732     clientComposition.emplace();
733     clientComposition->source.buffer.buffer = std::make_shared<
734             renderengine::impl::ExternalTexture>(mTestLayers[1]->layerFECompositionState.buffer,
735                                                  mRenderEngine,
736                                                  renderengine::impl::ExternalTexture::Usage::
737                                                          READABLE);
738     EXPECT_CALL(*mTestLayers[1]->layerFE, prepareClientComposition(_))
739             .WillOnce(Return(clientComposition));
740 
741     const std::vector<const LayerState*> layers = {
742             layerState0.get(),
743             layerState1.get(),
744     };
745 
746     initializeFlattener(layers);
747 
748     // layer 1 satisfies every condition in CachedSet::requiresHolePunch()
749     mTime += 200ms;
750     layerState1->resetFramesSinceBufferUpdate(); // it is updating
751 
752     initializeOverrideBuffer(layers);
753     // Expect no cache invalidation the first time (there's no cache yet)
754     EXPECT_EQ(getNonBufferHash(layers),
755               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
756 
757     // This will render a CachedSet of layer 0. Though it is just one layer, it satisfies the
758     // exception that there would be a hole punch above it.
759     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _))
760             .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
761     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
762 
763     // We've rendered a CachedSet, but we haven't merged it in.
764     EXPECT_EQ(nullptr, overrideBuffer0);
765 
766     // This time we merge the CachedSet in and we should still have only two sets.
767     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _)).Times(0);
768     initializeOverrideBuffer(layers);
769     EXPECT_EQ(getNonBufferHash(layers),
770               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
771     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
772 
773     EXPECT_NE(nullptr, overrideBuffer0); // got overridden
774     EXPECT_EQ(nullptr, overrideBuffer1); // did not
775 
776     // expect 0's peek though layer to be 1's output layer
777     const auto* peekThroughLayer0 =
778             layerState0->getOutputLayer()->getState().overrideInfo.peekThroughLayer;
779     const auto* peekThroughLayer1 =
780             layerState1->getOutputLayer()->getState().overrideInfo.peekThroughLayer;
781     EXPECT_EQ(&mTestLayers[1]->outputLayer, peekThroughLayer0);
782     EXPECT_EQ(nullptr, peekThroughLayer1);
783 }
784 
TEST_F(FlattenerTest,flattenLayers_holePunchSingleColorLayer)785 TEST_F(FlattenerTest, flattenLayers_holePunchSingleColorLayer) {
786     mTestLayers[0]->outputLayerCompositionState.displayFrame = Rect(0, 0, 5, 5);
787     mTestLayers[0]->layerFECompositionState.color = half4(255.f, 0.f, 0.f, 255.f);
788     mTestLayers[0]->layerFECompositionState.buffer = nullptr;
789 
790     // An opaque static background
791     auto& layerState0 = mTestLayers[0]->layerState;
792     const auto& overrideBuffer0 = layerState0->getOutputLayer()->getState().overrideInfo.buffer;
793 
794     // a rounded updating layer
795     auto& layerState1 = mTestLayers[1]->layerState;
796     const auto& overrideBuffer1 = layerState1->getOutputLayer()->getState().overrideInfo.buffer;
797     mTestLayers[1]->layerFECompositionState.blendMode = hal::BlendMode::NONE;
798 
799     EXPECT_CALL(*mTestLayers[1]->layerFE, hasRoundedCorners()).WillRepeatedly(Return(true));
800 
801     std::optional<LayerFE::LayerSettings> clientComposition;
802     clientComposition.emplace();
803     clientComposition->source.buffer.buffer = std::make_shared<
804             renderengine::impl::ExternalTexture>(mTestLayers[1]->layerFECompositionState.buffer,
805                                                  mRenderEngine,
806                                                  renderengine::impl::ExternalTexture::Usage::
807                                                          READABLE);
808     EXPECT_CALL(*mTestLayers[1]->layerFE, prepareClientComposition(_))
809             .WillOnce(Return(clientComposition));
810 
811     const std::vector<const LayerState*> layers = {
812             layerState0.get(),
813             layerState1.get(),
814     };
815 
816     initializeFlattener(layers);
817 
818     // layer 1 satisfies every condition in CachedSet::requiresHolePunch()
819     mTime += 200ms;
820     layerState1->resetFramesSinceBufferUpdate(); // it is updating
821 
822     initializeOverrideBuffer(layers);
823     // Expect no cache invalidation the first time (there's no cache yet)
824     EXPECT_EQ(getNonBufferHash(layers),
825               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
826 
827     // This will render a CachedSet of layer 0. Though it is just one layer, it satisfies the
828     // exception that there would be a hole punch above it.
829     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _))
830             .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
831     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
832 
833     // We've rendered a CachedSet, but we haven't merged it in.
834     EXPECT_EQ(nullptr, overrideBuffer0);
835 
836     // This time we merge the CachedSet in and we should still have only two sets.
837     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _)).Times(0);
838     initializeOverrideBuffer(layers);
839     EXPECT_EQ(getNonBufferHash(layers),
840               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
841     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
842 
843     EXPECT_NE(nullptr, overrideBuffer0); // got overridden
844     EXPECT_EQ(nullptr, overrideBuffer1); // did not
845 
846     // expect 0's peek though layer to be 1's output layer
847     const auto* peekThroughLayer0 =
848             layerState0->getOutputLayer()->getState().overrideInfo.peekThroughLayer;
849     const auto* peekThroughLayer1 =
850             layerState1->getOutputLayer()->getState().overrideInfo.peekThroughLayer;
851     EXPECT_EQ(&mTestLayers[1]->outputLayer, peekThroughLayer0);
852     EXPECT_EQ(nullptr, peekThroughLayer1);
853 }
854 
TEST_F(FlattenerTest,flattenLayers_flattensBlurBehindRunIfFirstRun)855 TEST_F(FlattenerTest, flattenLayers_flattensBlurBehindRunIfFirstRun) {
856     auto& layerState1 = mTestLayers[0]->layerState;
857 
858     auto& layerState2 = mTestLayers[1]->layerState;
859     mTestLayers[1]->layerFECompositionState.backgroundBlurRadius = 1;
860     layerState2->update(&mTestLayers[1]->outputLayer);
861 
862     auto& layerState3 = mTestLayers[2]->layerState;
863     const auto& overrideBuffer1 = layerState1->getOutputLayer()->getState().overrideInfo.buffer;
864     const auto& overrideBuffer2 = layerState2->getOutputLayer()->getState().overrideInfo.buffer;
865     const auto& overrideBuffer3 = layerState3->getOutputLayer()->getState().overrideInfo.buffer;
866 
867     const std::vector<const LayerState*> layers = {
868             layerState1.get(),
869             layerState2.get(),
870             layerState3.get(),
871     };
872 
873     initializeFlattener(layers);
874 
875     // Mark the first two layers inactive, which contain the blur behind
876     mTime += 200ms;
877     layerState3->resetFramesSinceBufferUpdate();
878 
879     // layers would be flattened but the buffer would not be overridden
880     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _))
881             .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
882 
883     initializeOverrideBuffer(layers);
884     EXPECT_EQ(getNonBufferHash(layers),
885               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
886     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
887 
888     for (const auto layer : layers) {
889         EXPECT_EQ(nullptr, layer->getOutputLayer()->getState().overrideInfo.buffer);
890     }
891 
892     // the new flattened layer is replaced
893     initializeOverrideBuffer(layers);
894     EXPECT_NE(getNonBufferHash(layers),
895               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
896     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
897     EXPECT_NE(nullptr, overrideBuffer1);
898     EXPECT_EQ(overrideBuffer1, overrideBuffer2);
899     EXPECT_EQ(nullptr, overrideBuffer3);
900 }
901 
TEST_F(FlattenerTest,flattenLayers_doesNotFlattenBlurBehindRun)902 TEST_F(FlattenerTest, flattenLayers_doesNotFlattenBlurBehindRun) {
903     auto& layerState1 = mTestLayers[0]->layerState;
904 
905     auto& layerState2 = mTestLayers[1]->layerState;
906     mTestLayers[1]->layerFECompositionState.backgroundBlurRadius = 1;
907     layerState2->update(&mTestLayers[1]->outputLayer);
908 
909     auto& layerState3 = mTestLayers[2]->layerState;
910 
911     const std::vector<const LayerState*> layers = {
912             layerState1.get(),
913             layerState2.get(),
914             layerState3.get(),
915     };
916 
917     initializeFlattener(layers);
918 
919     // Mark the last two layers inactive, which contains the blur layer, but does not contain the
920     // first layer
921     mTime += 200ms;
922     layerState1->resetFramesSinceBufferUpdate();
923 
924     // layers would be flattened but the buffer would not be overridden
925     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _))
926             .WillRepeatedly(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
927 
928     initializeOverrideBuffer(layers);
929     EXPECT_EQ(getNonBufferHash(layers),
930               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
931     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
932 
933     for (const auto layer : layers) {
934         EXPECT_EQ(nullptr, layer->getOutputLayer()->getState().overrideInfo.buffer);
935     }
936 
937     // nothing is flattened because the last two frames cannot be cached due to containing a blur
938     // layer
939     initializeOverrideBuffer(layers);
940     EXPECT_EQ(getNonBufferHash(layers),
941               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
942     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
943     for (const auto layer : layers) {
944         EXPECT_EQ(nullptr, layer->getOutputLayer()->getState().overrideInfo.buffer);
945     }
946 }
947 
TEST_F(FlattenerTest,flattenLayers_flattenSkipsLayerWithBlurBehind)948 TEST_F(FlattenerTest, flattenLayers_flattenSkipsLayerWithBlurBehind) {
949     auto& layerState1 = mTestLayers[0]->layerState;
950 
951     auto& layerStateWithBlurBehind = mTestLayers[1]->layerState;
952     mTestLayers[1]->layerFECompositionState.backgroundBlurRadius = 1;
953     layerStateWithBlurBehind->update(&mTestLayers[1]->outputLayer);
954 
955     auto& layerState3 = mTestLayers[2]->layerState;
956     auto& layerState4 = mTestLayers[3]->layerState;
957     const auto& overrideBuffer1 = layerState1->getOutputLayer()->getState().overrideInfo.buffer;
958     const auto& blurOverrideBuffer =
959             layerStateWithBlurBehind->getOutputLayer()->getState().overrideInfo.buffer;
960     const auto& overrideBuffer3 = layerState3->getOutputLayer()->getState().overrideInfo.buffer;
961     const auto& overrideBuffer4 = layerState4->getOutputLayer()->getState().overrideInfo.buffer;
962 
963     const std::vector<const LayerState*> layers = {
964             layerState1.get(),
965             layerStateWithBlurBehind.get(),
966             layerState3.get(),
967             layerState4.get(),
968     };
969 
970     initializeFlattener(layers);
971 
972     // Mark the last three layers inactive, which contains the blur layer, but does not contain the
973     // first layer
974     mTime += 200ms;
975     layerState1->resetFramesSinceBufferUpdate();
976 
977     // layers would be flattened but the buffer would not be overridden
978     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _))
979             .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
980 
981     initializeOverrideBuffer(layers);
982     EXPECT_EQ(getNonBufferHash(layers),
983               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
984     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
985 
986     for (const auto layer : layers) {
987         EXPECT_EQ(nullptr, layer->getOutputLayer()->getState().overrideInfo.buffer);
988     }
989 
990     // the new flattened layer is replaced
991     initializeOverrideBuffer(layers);
992     EXPECT_NE(getNonBufferHash(layers),
993               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
994     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
995     EXPECT_EQ(nullptr, overrideBuffer1);
996     EXPECT_EQ(nullptr, blurOverrideBuffer);
997     EXPECT_NE(nullptr, overrideBuffer3);
998     EXPECT_EQ(overrideBuffer3, overrideBuffer4);
999 }
1000 
TEST_F(FlattenerTest,flattenLayers_whenBlurLayerIsChanging_appliesBlurToInactiveBehindLayers)1001 TEST_F(FlattenerTest, flattenLayers_whenBlurLayerIsChanging_appliesBlurToInactiveBehindLayers) {
1002     auto& layerState1 = mTestLayers[0]->layerState;
1003     auto& layerState2 = mTestLayers[1]->layerState;
1004 
1005     auto& layerStateWithBlurBehind = mTestLayers[2]->layerState;
1006     mTestLayers[2]->layerFECompositionState.backgroundBlurRadius = 1;
1007     layerStateWithBlurBehind->update(&mTestLayers[2]->outputLayer);
1008     const auto& overrideBuffer1 = layerState1->getOutputLayer()->getState().overrideInfo.buffer;
1009     const auto& overrideBuffer2 = layerState2->getOutputLayer()->getState().overrideInfo.buffer;
1010     const auto& blurOverrideBuffer =
1011             layerStateWithBlurBehind->getOutputLayer()->getState().overrideInfo.buffer;
1012 
1013     const std::vector<const LayerState*> layers = {
1014             layerState1.get(),
1015             layerState2.get(),
1016             layerStateWithBlurBehind.get(),
1017     };
1018 
1019     initializeFlattener(layers);
1020 
1021     // Mark the first two layers inactive, but update the blur layer
1022     mTime += 200ms;
1023     layerStateWithBlurBehind->resetFramesSinceBufferUpdate();
1024 
1025     // layers would be flattened but the buffer would not be overridden
1026     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _))
1027             .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
1028 
1029     initializeOverrideBuffer(layers);
1030     EXPECT_EQ(getNonBufferHash(layers),
1031               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
1032     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
1033 
1034     const auto& cachedSet = mFlattener->getNewCachedSetForTesting();
1035     ASSERT_NE(std::nullopt, cachedSet);
1036     EXPECT_EQ(&mTestLayers[2]->outputLayer, cachedSet->getBlurLayer());
1037 
1038     for (const auto layer : layers) {
1039         EXPECT_EQ(nullptr, layer->getOutputLayer()->getState().overrideInfo.buffer);
1040     }
1041 
1042     // the new flattened layer is replaced
1043     initializeOverrideBuffer(layers);
1044     EXPECT_NE(getNonBufferHash(layers),
1045               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
1046     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
1047     EXPECT_NE(nullptr, overrideBuffer1);
1048     EXPECT_EQ(overrideBuffer2, overrideBuffer1);
1049     EXPECT_EQ(nullptr, blurOverrideBuffer);
1050 }
1051 
TEST_F(FlattenerTest,flattenLayers_renderCachedSets_doesNotRenderTwice)1052 TEST_F(FlattenerTest, flattenLayers_renderCachedSets_doesNotRenderTwice) {
1053     auto& layerState1 = mTestLayers[0]->layerState;
1054     auto& layerState2 = mTestLayers[1]->layerState;
1055     const auto& overrideBuffer1 = layerState1->getOutputLayer()->getState().overrideInfo.buffer;
1056     const auto& overrideBuffer2 = layerState2->getOutputLayer()->getState().overrideInfo.buffer;
1057 
1058     const std::vector<const LayerState*> layers = {
1059             layerState1.get(),
1060             layerState2.get(),
1061     };
1062 
1063     initializeFlattener(layers);
1064 
1065     // Mark the layers inactive
1066     mTime += 200ms;
1067     // layers would be flattened but the buffer would not be overridden
1068     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _))
1069             .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
1070 
1071     initializeOverrideBuffer(layers);
1072     EXPECT_EQ(getNonBufferHash(layers),
1073               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
1074     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
1075 
1076     EXPECT_EQ(nullptr, overrideBuffer1);
1077     EXPECT_EQ(nullptr, overrideBuffer2);
1078 
1079     // Simulate attempting to render prior to merging the new cached set with the layer stack.
1080     // Here we should not try to re-render.
1081     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _)).Times(0);
1082     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
1083 
1084     // We provide the override buffer now that it's rendered
1085     EXPECT_NE(getNonBufferHash(layers),
1086               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
1087     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
1088 
1089     EXPECT_NE(nullptr, overrideBuffer1);
1090     EXPECT_EQ(overrideBuffer2, overrideBuffer1);
1091 }
1092 
1093 const constexpr std::chrono::nanoseconds kCachedSetRenderDuration = 0ms;
1094 const constexpr size_t kMaxDeferRenderAttempts = 2;
1095 
1096 class FlattenerRenderSchedulingTest : public FlattenerTest {
1097 public:
FlattenerRenderSchedulingTest()1098     FlattenerRenderSchedulingTest()
1099           : FlattenerTest(
1100                     Flattener::Tunables{.mActiveLayerTimeout = 100ms,
1101                                         .mRenderScheduling = Flattener::Tunables::
1102                                                 RenderScheduling{.cachedSetRenderDuration =
1103                                                                          kCachedSetRenderDuration,
1104                                                                  .maxDeferRenderAttempts =
1105                                                                          kMaxDeferRenderAttempts},
1106                                         .mEnableHolePunch = true}) {}
1107 };
1108 
TEST_F(FlattenerRenderSchedulingTest,flattenLayers_renderCachedSets_defersUpToMaxAttempts)1109 TEST_F(FlattenerRenderSchedulingTest, flattenLayers_renderCachedSets_defersUpToMaxAttempts) {
1110     auto& layerState1 = mTestLayers[0]->layerState;
1111     auto& layerState2 = mTestLayers[1]->layerState;
1112 
1113     const std::vector<const LayerState*> layers = {
1114             layerState1.get(),
1115             layerState2.get(),
1116     };
1117 
1118     initializeFlattener(layers);
1119 
1120     // Mark the layers inactive
1121     mTime += 200ms;
1122 
1123     initializeOverrideBuffer(layers);
1124     EXPECT_EQ(getNonBufferHash(layers),
1125               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
1126 
1127     for (size_t i = 0; i < kMaxDeferRenderAttempts; i++) {
1128         EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _)).Times(0);
1129         mFlattener->renderCachedSets(mOutputState,
1130                                      std::chrono::steady_clock::now() -
1131                                              (kCachedSetRenderDuration + 10ms),
1132                                      true);
1133     }
1134 
1135     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _))
1136             .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
1137     mFlattener->renderCachedSets(mOutputState,
1138                                  std::chrono::steady_clock::now() -
1139                                          (kCachedSetRenderDuration + 10ms),
1140                                  true);
1141 }
1142 
TEST_F(FlattenerTest,flattenLayers_skipsLayersDisabledFromCaching)1143 TEST_F(FlattenerTest, flattenLayers_skipsLayersDisabledFromCaching) {
1144     auto& layerState1 = mTestLayers[0]->layerState;
1145     const auto& overrideBuffer1 = layerState1->getOutputLayer()->getState().overrideInfo.buffer;
1146 
1147     auto& layerState2 = mTestLayers[1]->layerState;
1148     const auto& overrideBuffer2 = layerState2->getOutputLayer()->getState().overrideInfo.buffer;
1149 
1150     // The third layer has a CachingHint that prevents caching from running
1151     auto& layerState3 = mTestLayers[2]->layerState;
1152     const auto& overrideBuffer3 = layerState3->getOutputLayer()->getState().overrideInfo.buffer;
1153     mTestLayers[2]->layerFECompositionState.cachingHint = gui::CachingHint::Disabled;
1154     mTestLayers[2]->layerState->update(&mTestLayers[2]->outputLayer);
1155 
1156     const std::vector<const LayerState*> layers = {
1157             layerState1.get(),
1158             layerState2.get(),
1159             layerState3.get(),
1160     };
1161 
1162     initializeFlattener(layers);
1163 
1164     mTime += 200ms;
1165     initializeOverrideBuffer(layers);
1166     EXPECT_EQ(getNonBufferHash(layers),
1167               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
1168 
1169     // This will render a CachedSet.
1170     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _))
1171             .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
1172     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
1173 
1174     // We've rendered a CachedSet, but we haven't merged it in.
1175     EXPECT_EQ(nullptr, overrideBuffer1);
1176     EXPECT_EQ(nullptr, overrideBuffer2);
1177     EXPECT_EQ(nullptr, overrideBuffer3);
1178 
1179     // This time we merge the CachedSet in, so we have a new hash, and we should
1180     // only have two sets.
1181     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _)).Times(0);
1182     initializeOverrideBuffer(layers);
1183     EXPECT_NE(getNonBufferHash(layers),
1184               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
1185     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
1186 
1187     EXPECT_NE(nullptr, overrideBuffer1);
1188     EXPECT_EQ(overrideBuffer1, overrideBuffer2);
1189     EXPECT_EQ(nullptr, overrideBuffer3);
1190 }
1191 
TEST_F(FlattenerTest,flattenLayers_skipsBT601_625)1192 TEST_F(FlattenerTest, flattenLayers_skipsBT601_625) {
1193     auto& layerState1 = mTestLayers[0]->layerState;
1194     const auto& overrideBuffer1 = layerState1->getOutputLayer()->getState().overrideInfo.buffer;
1195 
1196     auto& layerState2 = mTestLayers[1]->layerState;
1197     const auto& overrideBuffer2 = layerState2->getOutputLayer()->getState().overrideInfo.buffer;
1198 
1199     // The third layer uses a dataspace that will not be flattened due to
1200     // possible mismatch with DPU rendering.
1201     auto& layerState3 = mTestLayers[2]->layerState;
1202     const auto& overrideBuffer3 = layerState3->getOutputLayer()->getState().overrideInfo.buffer;
1203     mTestLayers[2]->outputLayerCompositionState.dataspace = ui::Dataspace::STANDARD_BT601_625;
1204     mTestLayers[2]->layerState->update(&mTestLayers[2]->outputLayer);
1205 
1206     const std::vector<const LayerState*> layers = {
1207             layerState1.get(),
1208             layerState2.get(),
1209             layerState3.get(),
1210     };
1211 
1212     initializeFlattener(layers);
1213 
1214     mTime += 200ms;
1215     initializeOverrideBuffer(layers);
1216     EXPECT_EQ(getNonBufferHash(layers),
1217               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
1218 
1219     // This will render a CachedSet.
1220     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _))
1221             .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
1222     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
1223 
1224     // We've rendered a CachedSet, but we haven't merged it in.
1225     EXPECT_EQ(nullptr, overrideBuffer1);
1226     EXPECT_EQ(nullptr, overrideBuffer2);
1227     EXPECT_EQ(nullptr, overrideBuffer3);
1228 
1229     // This time we merge the CachedSet in, so we have a new hash, and we should
1230     // only have two sets.
1231     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _)).Times(0);
1232     initializeOverrideBuffer(layers);
1233     EXPECT_NE(getNonBufferHash(layers),
1234               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
1235     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
1236 
1237     EXPECT_NE(nullptr, overrideBuffer1);
1238     EXPECT_EQ(overrideBuffer1, overrideBuffer2);
1239     EXPECT_EQ(nullptr, overrideBuffer3);
1240 }
1241 
TEST_F(FlattenerTest,flattenLayers_skipsHDR)1242 TEST_F(FlattenerTest, flattenLayers_skipsHDR) {
1243     auto& layerState1 = mTestLayers[0]->layerState;
1244     const auto& overrideBuffer1 = layerState1->getOutputLayer()->getState().overrideInfo.buffer;
1245 
1246     auto& layerState2 = mTestLayers[1]->layerState;
1247     const auto& overrideBuffer2 = layerState2->getOutputLayer()->getState().overrideInfo.buffer;
1248 
1249     // The third layer uses a dataspace that will not be flattened due to
1250     // possible mismatch with DPU rendering.
1251     auto& layerState3 = mTestLayers[2]->layerState;
1252     const auto& overrideBuffer3 = layerState3->getOutputLayer()->getState().overrideInfo.buffer;
1253     mTestLayers[2]->outputLayerCompositionState.dataspace = ui::Dataspace::BT2020_ITU_HLG;
1254     mTestLayers[2]->layerState->update(&mTestLayers[2]->outputLayer);
1255 
1256     const std::vector<const LayerState*> layers = {
1257             layerState1.get(),
1258             layerState2.get(),
1259             layerState3.get(),
1260     };
1261 
1262     initializeFlattener(layers);
1263 
1264     mTime += 200ms;
1265     initializeOverrideBuffer(layers);
1266     EXPECT_EQ(getNonBufferHash(layers),
1267               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
1268 
1269     // This will render a CachedSet.
1270     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _))
1271             .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
1272     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
1273 
1274     // We've rendered a CachedSet, but we haven't merged it in.
1275     EXPECT_EQ(nullptr, overrideBuffer1);
1276     EXPECT_EQ(nullptr, overrideBuffer2);
1277     EXPECT_EQ(nullptr, overrideBuffer3);
1278 
1279     // This time we merge the CachedSet in, so we have a new hash, and we should
1280     // only have two sets.
1281     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _)).Times(0);
1282     initializeOverrideBuffer(layers);
1283     EXPECT_NE(getNonBufferHash(layers),
1284               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
1285     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
1286 
1287     EXPECT_NE(nullptr, overrideBuffer1);
1288     EXPECT_EQ(overrideBuffer1, overrideBuffer2);
1289     EXPECT_EQ(nullptr, overrideBuffer3);
1290 }
1291 
TEST_F(FlattenerTest,flattenLayers_skipsHDR2)1292 TEST_F(FlattenerTest, flattenLayers_skipsHDR2) {
1293     auto& layerState1 = mTestLayers[0]->layerState;
1294     const auto& overrideBuffer1 = layerState1->getOutputLayer()->getState().overrideInfo.buffer;
1295 
1296     auto& layerState2 = mTestLayers[1]->layerState;
1297     const auto& overrideBuffer2 = layerState2->getOutputLayer()->getState().overrideInfo.buffer;
1298 
1299     // The third layer uses a dataspace that will not be flattened due to
1300     // possible mismatch with DPU rendering.
1301     auto& layerState3 = mTestLayers[2]->layerState;
1302     const auto& overrideBuffer3 = layerState3->getOutputLayer()->getState().overrideInfo.buffer;
1303     mTestLayers[2]->outputLayerCompositionState.dataspace = ui::Dataspace::BT2020_PQ;
1304     mTestLayers[2]->layerState->update(&mTestLayers[2]->outputLayer);
1305 
1306     const std::vector<const LayerState*> layers = {
1307             layerState1.get(),
1308             layerState2.get(),
1309             layerState3.get(),
1310     };
1311 
1312     initializeFlattener(layers);
1313 
1314     mTime += 200ms;
1315     initializeOverrideBuffer(layers);
1316     EXPECT_EQ(getNonBufferHash(layers),
1317               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
1318 
1319     // This will render a CachedSet.
1320     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _))
1321             .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
1322     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
1323 
1324     // We've rendered a CachedSet, but we haven't merged it in.
1325     EXPECT_EQ(nullptr, overrideBuffer1);
1326     EXPECT_EQ(nullptr, overrideBuffer2);
1327     EXPECT_EQ(nullptr, overrideBuffer3);
1328 
1329     // This time we merge the CachedSet in, so we have a new hash, and we should
1330     // only have two sets.
1331     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _)).Times(0);
1332     initializeOverrideBuffer(layers);
1333     EXPECT_NE(getNonBufferHash(layers),
1334               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
1335     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
1336 
1337     EXPECT_NE(nullptr, overrideBuffer1);
1338     EXPECT_EQ(overrideBuffer1, overrideBuffer2);
1339     EXPECT_EQ(nullptr, overrideBuffer3);
1340 }
1341 
TEST_F(FlattenerTest,flattenLayers_skipsLayersDisablingDimming)1342 TEST_F(FlattenerTest, flattenLayers_skipsLayersDisablingDimming) {
1343     auto& layerState1 = mTestLayers[0]->layerState;
1344     const auto& overrideBuffer1 = layerState1->getOutputLayer()->getState().overrideInfo.buffer;
1345 
1346     auto& layerState2 = mTestLayers[1]->layerState;
1347     const auto& overrideBuffer2 = layerState2->getOutputLayer()->getState().overrideInfo.buffer;
1348 
1349     // The third layer disables dimming, which means it should not be cached
1350     auto& layerState3 = mTestLayers[2]->layerState;
1351     const auto& overrideBuffer3 = layerState3->getOutputLayer()->getState().overrideInfo.buffer;
1352     mTestLayers[2]->layerFECompositionState.dimmingEnabled = false;
1353     mTestLayers[2]->layerState->update(&mTestLayers[2]->outputLayer);
1354 
1355     const std::vector<const LayerState*> layers = {
1356             layerState1.get(),
1357             layerState2.get(),
1358             layerState3.get(),
1359     };
1360 
1361     initializeFlattener(layers);
1362 
1363     mTime += 200ms;
1364     initializeOverrideBuffer(layers);
1365     EXPECT_EQ(getNonBufferHash(layers),
1366               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
1367 
1368     // This will render a CachedSet.
1369     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _))
1370             .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
1371     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
1372 
1373     // We've rendered a CachedSet, but we haven't merged it in.
1374     EXPECT_EQ(nullptr, overrideBuffer1);
1375     EXPECT_EQ(nullptr, overrideBuffer2);
1376     EXPECT_EQ(nullptr, overrideBuffer3);
1377 
1378     // This time we merge the CachedSet in, so we have a new hash, and we should
1379     // only have two sets.
1380     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _)).Times(0);
1381     initializeOverrideBuffer(layers);
1382     EXPECT_NE(getNonBufferHash(layers),
1383               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
1384     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
1385 
1386     EXPECT_NE(nullptr, overrideBuffer1);
1387     EXPECT_EQ(overrideBuffer1, overrideBuffer2);
1388     EXPECT_EQ(nullptr, overrideBuffer3);
1389 }
1390 
TEST_F(FlattenerTest,flattenLayers_skipsColorLayers)1391 TEST_F(FlattenerTest, flattenLayers_skipsColorLayers) {
1392     auto& layerState1 = mTestLayers[0]->layerState;
1393     const auto& overrideBuffer1 = layerState1->getOutputLayer()->getState().overrideInfo.buffer;
1394     auto& layerState2 = mTestLayers[1]->layerState;
1395     const auto& overrideBuffer2 = layerState2->getOutputLayer()->getState().overrideInfo.buffer;
1396     auto& layerState3 = mTestLayers[2]->layerState;
1397     const auto& overrideBuffer3 = layerState3->getOutputLayer()->getState().overrideInfo.buffer;
1398     auto& layerState4 = mTestLayers[3]->layerState;
1399     const auto& overrideBuffer4 = layerState4->getOutputLayer()->getState().overrideInfo.buffer;
1400 
1401     // Rewrite the first two layers to just be a solid color.
1402     mTestLayers[0]->layerFECompositionState.color = half4(255.f, 0.f, 0.f, 255.f);
1403     mTestLayers[0]->layerFECompositionState.buffer = nullptr;
1404     mTestLayers[1]->layerFECompositionState.color = half4(0.f, 255.f, 0.f, 255.f);
1405     mTestLayers[1]->layerFECompositionState.buffer = nullptr;
1406 
1407     const std::vector<const LayerState*> layers = {
1408             layerState1.get(),
1409             layerState2.get(),
1410             layerState3.get(),
1411             layerState4.get(),
1412     };
1413 
1414     initializeFlattener(layers);
1415 
1416     mTime += 200ms;
1417     initializeOverrideBuffer(layers);
1418     EXPECT_EQ(getNonBufferHash(layers),
1419               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
1420 
1421     // This will render a CachedSet.
1422     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _))
1423             .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
1424     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
1425 
1426     // We've rendered a CachedSet, but we haven't merged it in.
1427     EXPECT_EQ(nullptr, overrideBuffer1);
1428     EXPECT_EQ(nullptr, overrideBuffer2);
1429     EXPECT_EQ(nullptr, overrideBuffer3);
1430     EXPECT_EQ(nullptr, overrideBuffer4);
1431 
1432     // This time we merge the CachedSet in, so we have a new hash, and we should
1433     // only have two sets.
1434     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _)).Times(0);
1435     initializeOverrideBuffer(layers);
1436     EXPECT_NE(getNonBufferHash(layers),
1437               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
1438     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
1439 
1440     EXPECT_EQ(nullptr, overrideBuffer1);
1441     EXPECT_EQ(nullptr, overrideBuffer2);
1442     EXPECT_EQ(overrideBuffer3, overrideBuffer4);
1443     EXPECT_NE(nullptr, overrideBuffer4);
1444 }
1445 
TEST_F(FlattenerTest,flattenLayers_includes_DISPLAY_DECORATION)1446 TEST_F(FlattenerTest, flattenLayers_includes_DISPLAY_DECORATION) {
1447     auto& layerState1 = mTestLayers[0]->layerState;
1448     const auto& overrideBuffer1 = layerState1->getOutputLayer()->getState().overrideInfo.buffer;
1449 
1450     auto& layerState2 = mTestLayers[1]->layerState;
1451     const auto& overrideBuffer2 = layerState2->getOutputLayer()->getState().overrideInfo.buffer;
1452 
1453     // The third layer uses DISPLAY_DECORATION, which should be cached.
1454     auto& layerState3 = mTestLayers[2]->layerState;
1455     const auto& overrideBuffer3 = layerState3->getOutputLayer()->getState().overrideInfo.buffer;
1456     mTestLayers[2]->layerFECompositionState.compositionType =
1457             aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
1458     mTestLayers[2]->layerState->update(&mTestLayers[2]->outputLayer);
1459 
1460     const std::vector<const LayerState*> layers = {
1461             layerState1.get(),
1462             layerState2.get(),
1463             layerState3.get(),
1464     };
1465 
1466     initializeFlattener(layers);
1467 
1468     mTime += 200ms;
1469     initializeOverrideBuffer(layers);
1470     EXPECT_EQ(getNonBufferHash(layers),
1471               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
1472 
1473     // This will render a CachedSet.
1474     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _))
1475             .WillOnce(Return(ByMove(ftl::yield<FenceResult>(Fence::NO_FENCE))));
1476     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
1477 
1478     // We've rendered a CachedSet, but we haven't merged it in.
1479     EXPECT_EQ(nullptr, overrideBuffer1);
1480     EXPECT_EQ(nullptr, overrideBuffer2);
1481     EXPECT_EQ(nullptr, overrideBuffer3);
1482 
1483     // This time we merge the CachedSet in, so we have a new hash, and we should
1484     // only have two sets.
1485     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _)).Times(0);
1486     initializeOverrideBuffer(layers);
1487     EXPECT_NE(getNonBufferHash(layers),
1488               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
1489     mFlattener->renderCachedSets(mOutputState, std::nullopt, true);
1490 
1491     EXPECT_NE(nullptr, overrideBuffer1);
1492     EXPECT_EQ(overrideBuffer1, overrideBuffer2);
1493     EXPECT_EQ(overrideBuffer1, overrideBuffer3);
1494 }
1495 
1496 } // namespace
1497 } // namespace android::compositionengine
1498