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