• 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/mock/RenderEngine.h>
27 #include <chrono>
28 
29 namespace android::compositionengine {
30 using namespace std::chrono_literals;
31 using impl::planner::CachedSet;
32 using impl::planner::Flattener;
33 using impl::planner::LayerState;
34 using impl::planner::NonBufferHash;
35 
36 using testing::_;
37 using testing::ByMove;
38 using testing::ByRef;
39 using testing::DoAll;
40 using testing::Invoke;
41 using testing::Return;
42 using testing::ReturnRef;
43 using testing::Sequence;
44 using testing::SetArgPointee;
45 
46 namespace {
47 
48 class TestableFlattener : public Flattener {
49 public:
TestableFlattener(renderengine::RenderEngine & renderEngine,bool enableHolePunch,std::optional<Flattener::CachedSetRenderSchedulingTunables> cachedSetRenderSchedulingTunables=std::nullopt)50     TestableFlattener(renderengine::RenderEngine& renderEngine, bool enableHolePunch,
51                       std::optional<Flattener::CachedSetRenderSchedulingTunables>
52                               cachedSetRenderSchedulingTunables = std::nullopt)
53           : Flattener(renderEngine, enableHolePunch, cachedSetRenderSchedulingTunables) {}
getNewCachedSetForTesting() const54     const std::optional<CachedSet>& getNewCachedSetForTesting() const { return mNewCachedSet; }
55 };
56 
57 class FlattenerTest : public testing::Test {
58 public:
FlattenerTest()59     FlattenerTest() : FlattenerTest(std::nullopt) {}
60     void SetUp() override;
61 
62 protected:
FlattenerTest(std::optional<Flattener::CachedSetRenderSchedulingTunables> cachedSetRenderSchedulingTunables)63     FlattenerTest(std::optional<Flattener::CachedSetRenderSchedulingTunables>
64                           cachedSetRenderSchedulingTunables)
65           : mFlattener(std::make_unique<TestableFlattener>(mRenderEngine, true,
66                                                            cachedSetRenderSchedulingTunables)) {}
67     void initializeOverrideBuffer(const std::vector<const LayerState*>& layers);
68     void initializeFlattener(const std::vector<const LayerState*>& layers);
69     void expectAllLayersFlattened(const std::vector<const LayerState*>& layers);
70 
71     // mRenderEngine is held as a reference in mFlattener, so explicitly destroy mFlattener first.
72     renderengine::mock::RenderEngine mRenderEngine;
73     std::unique_ptr<TestableFlattener> mFlattener;
74 
75     const std::chrono::steady_clock::time_point kStartTime = std::chrono::steady_clock::now();
76     std::chrono::steady_clock::time_point mTime = kStartTime;
77 
78     struct TestLayer {
79         std::string name;
80         mock::OutputLayer outputLayer;
81         impl::OutputLayerCompositionState outputLayerCompositionState;
82         // LayerFE inherits from RefBase and must be held by an sp<>
83         sp<mock::LayerFE> layerFE;
84         LayerFECompositionState layerFECompositionState;
85 
86         std::unique_ptr<LayerState> layerState;
87     };
88 
89     static constexpr size_t kNumLayers = 5;
90     std::vector<std::unique_ptr<TestLayer>> mTestLayers;
91     impl::OutputCompositionState mOutputState;
92 };
93 
SetUp()94 void FlattenerTest::SetUp() {
95     mFlattener->setDisplaySize({1, 1});
96     for (size_t i = 0; i < kNumLayers; i++) {
97         auto testLayer = std::make_unique<TestLayer>();
98         auto pos = static_cast<int32_t>(i);
99         std::stringstream ss;
100         ss << "testLayer" << i;
101         testLayer->name = ss.str();
102 
103         testLayer->outputLayerCompositionState.displayFrame = Rect(pos, pos, pos + 1, pos + 1);
104         testLayer->outputLayerCompositionState.visibleRegion =
105                 Region(Rect(pos + 1, pos + 1, pos + 2, pos + 2));
106 
107         testLayer->layerFECompositionState.buffer =
108                 new GraphicBuffer(100, 100, HAL_PIXEL_FORMAT_RGBA_8888, 1,
109                                   GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
110                                           GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE,
111                                   "output");
112 
113         testLayer->layerFE = sp<mock::LayerFE>::make();
114 
115         EXPECT_CALL(*testLayer->layerFE, getSequence)
116                 .WillRepeatedly(Return(static_cast<int32_t>(i)));
117         EXPECT_CALL(*testLayer->layerFE, getDebugName)
118                 .WillRepeatedly(Return(testLayer->name.c_str()));
119         EXPECT_CALL(*testLayer->layerFE, getCompositionState)
120                 .WillRepeatedly(Return(&testLayer->layerFECompositionState));
121 
122         std::vector<LayerFE::LayerSettings> clientCompositionList = {
123                 LayerFE::LayerSettings{},
124         };
125 
126         EXPECT_CALL(*testLayer->layerFE, prepareClientCompositionList)
127                 .WillRepeatedly(Return(clientCompositionList));
128         EXPECT_CALL(testLayer->outputLayer, getLayerFE)
129                 .WillRepeatedly(ReturnRef(*testLayer->layerFE));
130         EXPECT_CALL(testLayer->outputLayer, getState)
131                 .WillRepeatedly(ReturnRef(testLayer->outputLayerCompositionState));
132         EXPECT_CALL(testLayer->outputLayer, editState)
133                 .WillRepeatedly(ReturnRef(testLayer->outputLayerCompositionState));
134 
135         testLayer->layerState = std::make_unique<LayerState>(&testLayer->outputLayer);
136         testLayer->layerState->incrementFramesSinceBufferUpdate();
137 
138         mTestLayers.emplace_back(std::move(testLayer));
139 
140         // set up minimium params needed for rendering
141         mOutputState.dataspace = ui::Dataspace::SRGB;
142         mOutputState.framebufferSpace = ProjectionSpace(ui::Size(10, 20), Rect(10, 5));
143         mOutputState.framebufferSpace.orientation = ui::ROTATION_90;
144     }
145 }
146 
initializeOverrideBuffer(const std::vector<const LayerState * > & layers)147 void FlattenerTest::initializeOverrideBuffer(const std::vector<const LayerState*>& layers) {
148     for (const auto layer : layers) {
149         layer->getOutputLayer()->editState().overrideInfo = {};
150     }
151 }
152 
initializeFlattener(const std::vector<const LayerState * > & layers)153 void FlattenerTest::initializeFlattener(const std::vector<const LayerState*>& layers) {
154     // layer stack is unknown, reset current geomentry
155     initializeOverrideBuffer(layers);
156     EXPECT_EQ(getNonBufferHash(layers),
157               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
158     mFlattener->renderCachedSets(mOutputState, std::nullopt);
159 
160     // same geometry, update the internal layer stack
161     initializeOverrideBuffer(layers);
162     EXPECT_EQ(getNonBufferHash(layers),
163               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
164     mFlattener->renderCachedSets(mOutputState, std::nullopt);
165 }
166 
expectAllLayersFlattened(const std::vector<const LayerState * > & layers)167 void FlattenerTest::expectAllLayersFlattened(const std::vector<const LayerState*>& layers) {
168     // layers would be flattened but the buffer would not be overridden
169     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _, _, _)).WillOnce(Return(NO_ERROR));
170 
171     initializeOverrideBuffer(layers);
172     EXPECT_EQ(getNonBufferHash(layers),
173               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
174     mFlattener->renderCachedSets(mOutputState, std::nullopt);
175 
176     for (const auto layer : layers) {
177         EXPECT_EQ(nullptr, layer->getOutputLayer()->getState().overrideInfo.buffer);
178     }
179 
180     // the new flattened layer is replaced
181     initializeOverrideBuffer(layers);
182     EXPECT_NE(getNonBufferHash(layers),
183               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
184     mFlattener->renderCachedSets(mOutputState, std::nullopt);
185 
186     const auto buffer = layers[0]->getOutputLayer()->getState().overrideInfo.buffer;
187     EXPECT_NE(nullptr, buffer);
188     for (const auto layer : layers) {
189         EXPECT_EQ(buffer, layer->getOutputLayer()->getState().overrideInfo.buffer);
190     }
191 }
192 
TEST_F(FlattenerTest,flattenLayers_NewLayerStack)193 TEST_F(FlattenerTest, flattenLayers_NewLayerStack) {
194     auto& layerState1 = mTestLayers[0]->layerState;
195     auto& layerState2 = mTestLayers[1]->layerState;
196 
197     const std::vector<const LayerState*> layers = {
198             layerState1.get(),
199             layerState2.get(),
200     };
201     initializeFlattener(layers);
202 }
203 
TEST_F(FlattenerTest,flattenLayers_ActiveLayersAreNotFlattened)204 TEST_F(FlattenerTest, flattenLayers_ActiveLayersAreNotFlattened) {
205     auto& layerState1 = mTestLayers[0]->layerState;
206     auto& layerState2 = mTestLayers[1]->layerState;
207 
208     const std::vector<const LayerState*> layers = {
209             layerState1.get(),
210             layerState2.get(),
211     };
212 
213     initializeFlattener(layers);
214 
215     // layers cannot be flattened yet, since they are still active
216     initializeOverrideBuffer(layers);
217     EXPECT_EQ(getNonBufferHash(layers),
218               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
219     mFlattener->renderCachedSets(mOutputState, std::nullopt);
220 }
221 
TEST_F(FlattenerTest,flattenLayers_basicFlatten)222 TEST_F(FlattenerTest, flattenLayers_basicFlatten) {
223     auto& layerState1 = mTestLayers[0]->layerState;
224     auto& layerState2 = mTestLayers[1]->layerState;
225     auto& layerState3 = mTestLayers[2]->layerState;
226 
227     const std::vector<const LayerState*> layers = {
228             layerState1.get(),
229             layerState2.get(),
230             layerState3.get(),
231     };
232 
233     initializeFlattener(layers);
234 
235     // make all layers inactive
236     mTime += 200ms;
237     expectAllLayersFlattened(layers);
238 }
239 
TEST_F(FlattenerTest,flattenLayers_FlattenedLayersStayFlattenWhenNoUpdate)240 TEST_F(FlattenerTest, flattenLayers_FlattenedLayersStayFlattenWhenNoUpdate) {
241     auto& layerState1 = mTestLayers[0]->layerState;
242     const auto& overrideBuffer1 = layerState1->getOutputLayer()->getState().overrideInfo.buffer;
243 
244     auto& layerState2 = mTestLayers[1]->layerState;
245     const auto& overrideBuffer2 = layerState2->getOutputLayer()->getState().overrideInfo.buffer;
246 
247     auto& layerState3 = mTestLayers[2]->layerState;
248     const auto& overrideBuffer3 = layerState3->getOutputLayer()->getState().overrideInfo.buffer;
249 
250     const std::vector<const LayerState*> layers = {
251             layerState1.get(),
252             layerState2.get(),
253             layerState3.get(),
254     };
255 
256     initializeFlattener(layers);
257 
258     // make all layers inactive
259     mTime += 200ms;
260     expectAllLayersFlattened(layers);
261 
262     initializeOverrideBuffer(layers);
263     EXPECT_NE(getNonBufferHash(layers),
264               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
265     mFlattener->renderCachedSets(mOutputState, std::nullopt);
266 
267     EXPECT_NE(nullptr, overrideBuffer1);
268     EXPECT_EQ(overrideBuffer1, overrideBuffer2);
269     EXPECT_EQ(overrideBuffer2, overrideBuffer3);
270 }
271 
TEST_F(FlattenerTest,flattenLayers_FlattenedLayersSetsProjectionSpace)272 TEST_F(FlattenerTest, flattenLayers_FlattenedLayersSetsProjectionSpace) {
273     auto& layerState1 = mTestLayers[0]->layerState;
274     const auto& overrideDisplaySpace =
275             layerState1->getOutputLayer()->getState().overrideInfo.displaySpace;
276 
277     auto& layerState2 = mTestLayers[1]->layerState;
278 
279     const std::vector<const LayerState*> layers = {
280             layerState1.get(),
281             layerState2.get(),
282     };
283 
284     initializeFlattener(layers);
285 
286     // make all layers inactive
287     mTime += 200ms;
288     expectAllLayersFlattened(layers);
289 
290     EXPECT_EQ(overrideDisplaySpace, mOutputState.framebufferSpace);
291 }
292 
TEST_F(FlattenerTest,flattenLayers_FlattenedLayersSetsDamageRegions)293 TEST_F(FlattenerTest, flattenLayers_FlattenedLayersSetsDamageRegions) {
294     auto& layerState1 = mTestLayers[0]->layerState;
295     const auto& overrideDamageRegion =
296             layerState1->getOutputLayer()->getState().overrideInfo.damageRegion;
297 
298     auto& layerState2 = mTestLayers[1]->layerState;
299 
300     const std::vector<const LayerState*> layers = {
301             layerState1.get(),
302             layerState2.get(),
303     };
304 
305     initializeFlattener(layers);
306 
307     // make all layers inactive
308     mTime += 200ms;
309     expectAllLayersFlattened(layers);
310     EXPECT_TRUE(overrideDamageRegion.isRect() &&
311                 overrideDamageRegion.bounds() == Rect::INVALID_RECT);
312 
313     initializeOverrideBuffer(layers);
314     EXPECT_NE(getNonBufferHash(layers),
315               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
316     EXPECT_TRUE(overrideDamageRegion.isRect() && overrideDamageRegion.bounds() == Rect::EMPTY_RECT);
317 }
318 
TEST_F(FlattenerTest,flattenLayers_FlattenedLayersSetsVisibleRegion)319 TEST_F(FlattenerTest, flattenLayers_FlattenedLayersSetsVisibleRegion) {
320     auto& layerState1 = mTestLayers[0]->layerState;
321     const auto& overrideVisibleRegion =
322             layerState1->getOutputLayer()->getState().overrideInfo.visibleRegion;
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     Region expectedRegion;
337     expectedRegion.orSelf(Rect(1, 1, 2, 2));
338     expectedRegion.orSelf(Rect(2, 2, 3, 3));
339     EXPECT_TRUE(overrideVisibleRegion.hasSameRects(expectedRegion));
340 }
341 
TEST_F(FlattenerTest,flattenLayers_addLayerToFlattenedCauseReset)342 TEST_F(FlattenerTest, flattenLayers_addLayerToFlattenedCauseReset) {
343     auto& layerState1 = mTestLayers[0]->layerState;
344     const auto& overrideBuffer1 = layerState1->getOutputLayer()->getState().overrideInfo.buffer;
345 
346     auto& layerState2 = mTestLayers[1]->layerState;
347     const auto& overrideBuffer2 = layerState2->getOutputLayer()->getState().overrideInfo.buffer;
348 
349     auto& layerState3 = mTestLayers[2]->layerState;
350     const auto& overrideBuffer3 = layerState3->getOutputLayer()->getState().overrideInfo.buffer;
351 
352     std::vector<const LayerState*> layers = {
353             layerState1.get(),
354             layerState2.get(),
355     };
356 
357     initializeFlattener(layers);
358     // make all layers inactive
359     mTime += 200ms;
360 
361     initializeOverrideBuffer(layers);
362     expectAllLayersFlattened(layers);
363 
364     // add a new layer to the stack, this will cause all the flatenner to reset
365     layers.push_back(layerState3.get());
366 
367     initializeOverrideBuffer(layers);
368     EXPECT_EQ(getNonBufferHash(layers),
369               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
370     mFlattener->renderCachedSets(mOutputState, std::nullopt);
371 
372     EXPECT_EQ(nullptr, overrideBuffer1);
373     EXPECT_EQ(nullptr, overrideBuffer2);
374     EXPECT_EQ(nullptr, overrideBuffer3);
375 }
376 
TEST_F(FlattenerTest,flattenLayers_BufferUpdateToFlatten)377 TEST_F(FlattenerTest, flattenLayers_BufferUpdateToFlatten) {
378     auto& layerState1 = mTestLayers[0]->layerState;
379     const auto& overrideBuffer1 = layerState1->getOutputLayer()->getState().overrideInfo.buffer;
380 
381     auto& layerState2 = mTestLayers[1]->layerState;
382     const auto& overrideBuffer2 = layerState2->getOutputLayer()->getState().overrideInfo.buffer;
383 
384     auto& layerState3 = mTestLayers[2]->layerState;
385     const auto& overrideBuffer3 = layerState3->getOutputLayer()->getState().overrideInfo.buffer;
386 
387     const std::vector<const LayerState*> layers = {
388             layerState1.get(),
389             layerState2.get(),
390             layerState3.get(),
391     };
392 
393     initializeFlattener(layers);
394 
395     // make all layers inactive
396     mTime += 200ms;
397     expectAllLayersFlattened(layers);
398 
399     // Layer 1 posted a buffer update, layers would be decomposed, and a new drawFrame would be
400     // caleed for Layer2 and Layer3
401     layerState1->resetFramesSinceBufferUpdate();
402 
403     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _, _, _)).WillOnce(Return(NO_ERROR));
404     initializeOverrideBuffer(layers);
405     EXPECT_EQ(getNonBufferHash(layers),
406               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
407     mFlattener->renderCachedSets(mOutputState, std::nullopt);
408 
409     EXPECT_EQ(nullptr, overrideBuffer1);
410     EXPECT_EQ(nullptr, overrideBuffer2);
411     EXPECT_EQ(nullptr, overrideBuffer3);
412 
413     initializeOverrideBuffer(layers);
414     EXPECT_NE(getNonBufferHash(layers),
415               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
416     mFlattener->renderCachedSets(mOutputState, std::nullopt);
417 
418     EXPECT_EQ(nullptr, overrideBuffer1);
419     EXPECT_NE(nullptr, overrideBuffer2);
420     EXPECT_EQ(overrideBuffer2, overrideBuffer3);
421 
422     layerState1->incrementFramesSinceBufferUpdate();
423     mTime += 200ms;
424 
425     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _, _, _)).WillOnce(Return(NO_ERROR));
426     initializeOverrideBuffer(layers);
427     EXPECT_NE(getNonBufferHash(layers),
428               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
429     mFlattener->renderCachedSets(mOutputState, std::nullopt);
430 
431     EXPECT_EQ(nullptr, overrideBuffer1);
432     EXPECT_NE(nullptr, overrideBuffer2);
433     EXPECT_EQ(overrideBuffer2, overrideBuffer3);
434 
435     initializeOverrideBuffer(layers);
436     EXPECT_NE(getNonBufferHash(layers),
437               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
438     mFlattener->renderCachedSets(mOutputState, std::nullopt);
439 
440     EXPECT_NE(nullptr, overrideBuffer1);
441     EXPECT_EQ(overrideBuffer1, overrideBuffer2);
442     EXPECT_EQ(overrideBuffer2, overrideBuffer3);
443 }
444 
TEST_F(FlattenerTest,flattenLayers_BufferUpdateForMiddleLayer)445 TEST_F(FlattenerTest, flattenLayers_BufferUpdateForMiddleLayer) {
446     auto& layerState1 = mTestLayers[0]->layerState;
447     const auto& overrideBuffer1 = layerState1->getOutputLayer()->getState().overrideInfo.buffer;
448 
449     auto& layerState2 = mTestLayers[1]->layerState;
450     const auto& overrideBuffer2 = layerState2->getOutputLayer()->getState().overrideInfo.buffer;
451 
452     auto& layerState3 = mTestLayers[2]->layerState;
453     const auto& overrideBuffer3 = layerState3->getOutputLayer()->getState().overrideInfo.buffer;
454 
455     auto& layerState4 = mTestLayers[3]->layerState;
456     const auto& overrideBuffer4 = layerState4->getOutputLayer()->getState().overrideInfo.buffer;
457 
458     auto& layerState5 = mTestLayers[4]->layerState;
459     const auto& overrideBuffer5 = layerState5->getOutputLayer()->getState().overrideInfo.buffer;
460 
461     const std::vector<const LayerState*> layers = {
462             layerState1.get(), layerState2.get(), layerState3.get(),
463             layerState4.get(), layerState5.get(),
464     };
465 
466     initializeFlattener(layers);
467 
468     // make all layers inactive
469     mTime += 200ms;
470     expectAllLayersFlattened(layers);
471 
472     // Layer 3 posted a buffer update, layers would be decomposed, and a new drawFrame would be
473     // called for Layer1 and Layer2
474     layerState3->resetFramesSinceBufferUpdate();
475 
476     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _, _, _)).WillOnce(Return(NO_ERROR));
477     initializeOverrideBuffer(layers);
478     EXPECT_EQ(getNonBufferHash(layers),
479               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
480     mFlattener->renderCachedSets(mOutputState, std::nullopt);
481 
482     EXPECT_EQ(nullptr, overrideBuffer1);
483     EXPECT_EQ(nullptr, overrideBuffer2);
484     EXPECT_EQ(nullptr, overrideBuffer3);
485     EXPECT_EQ(nullptr, overrideBuffer4);
486     EXPECT_EQ(nullptr, overrideBuffer5);
487 
488     // Layers 1 and 2 will be flattened a new drawFrame would be called for Layer4 and Layer5
489     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _, _, _)).WillOnce(Return(NO_ERROR));
490     initializeOverrideBuffer(layers);
491     EXPECT_NE(getNonBufferHash(layers),
492               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
493     mOutputState.framebufferSpace.orientation = ui::ROTATION_90;
494     mFlattener->renderCachedSets(mOutputState, std::nullopt);
495 
496     EXPECT_NE(nullptr, overrideBuffer1);
497     EXPECT_EQ(overrideBuffer1, overrideBuffer2);
498     EXPECT_EQ(nullptr, overrideBuffer3);
499     EXPECT_EQ(nullptr, overrideBuffer4);
500     EXPECT_EQ(nullptr, overrideBuffer5);
501 
502     // Layers 4 and 5 will be flattened
503     initializeOverrideBuffer(layers);
504     EXPECT_NE(getNonBufferHash(layers),
505               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
506     mOutputState.framebufferSpace.orientation = ui::ROTATION_180;
507     mFlattener->renderCachedSets(mOutputState, std::nullopt);
508 
509     EXPECT_NE(nullptr, overrideBuffer1);
510     EXPECT_EQ(overrideBuffer1, overrideBuffer2);
511     EXPECT_EQ(nullptr, overrideBuffer3);
512     EXPECT_NE(nullptr, overrideBuffer4);
513     EXPECT_EQ(overrideBuffer4, overrideBuffer5);
514 
515     layerState3->incrementFramesSinceBufferUpdate();
516     mTime += 200ms;
517 
518     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _, _, _)).WillOnce(Return(NO_ERROR));
519     initializeOverrideBuffer(layers);
520     EXPECT_NE(getNonBufferHash(layers),
521               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
522     mFlattener->renderCachedSets(mOutputState, std::nullopt);
523 
524     EXPECT_NE(nullptr, overrideBuffer1);
525     EXPECT_EQ(overrideBuffer1, overrideBuffer2);
526     EXPECT_EQ(nullptr, overrideBuffer3);
527     EXPECT_NE(nullptr, overrideBuffer4);
528     EXPECT_EQ(overrideBuffer4, overrideBuffer5);
529 
530     initializeOverrideBuffer(layers);
531     EXPECT_NE(getNonBufferHash(layers),
532               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
533     mOutputState.framebufferSpace.orientation = ui::ROTATION_270;
534     mFlattener->renderCachedSets(mOutputState, std::nullopt);
535 
536     EXPECT_NE(nullptr, overrideBuffer1);
537     EXPECT_EQ(overrideBuffer1, overrideBuffer2);
538     EXPECT_EQ(overrideBuffer2, overrideBuffer3);
539     EXPECT_EQ(overrideBuffer3, overrideBuffer4);
540     EXPECT_EQ(overrideBuffer4, overrideBuffer5);
541 }
542 
543 // Tests for a PIP
TEST_F(FlattenerTest,flattenLayers_pipRequiresRoundedCorners)544 TEST_F(FlattenerTest, flattenLayers_pipRequiresRoundedCorners) {
545     auto& layerState1 = mTestLayers[0]->layerState;
546     const auto& overrideBuffer1 = layerState1->getOutputLayer()->getState().overrideInfo.buffer;
547 
548     auto& layerState2 = mTestLayers[1]->layerState;
549     const auto& overrideBuffer2 = layerState2->getOutputLayer()->getState().overrideInfo.buffer;
550 
551     auto& layerState3 = mTestLayers[2]->layerState;
552     const auto& overrideBuffer3 = layerState3->getOutputLayer()->getState().overrideInfo.buffer;
553 
554     const std::vector<const LayerState*> layers = {
555             layerState1.get(),
556             layerState2.get(),
557             layerState3.get(),
558     };
559 
560     initializeFlattener(layers);
561 
562     // 3 has a buffer update, so it will not be merged, but it has no round
563     // corners, so it is not a PIP.
564     mTime += 200ms;
565     layerState3->resetFramesSinceBufferUpdate();
566 
567     initializeOverrideBuffer(layers);
568     EXPECT_EQ(getNonBufferHash(layers),
569               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
570 
571     // This will render a CachedSet.
572     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _, _, _)).WillOnce(Return(NO_ERROR));
573     mFlattener->renderCachedSets(mOutputState, std::nullopt);
574 
575     // We've rendered a CachedSet, but we haven't merged it in.
576     EXPECT_EQ(nullptr, overrideBuffer1);
577     EXPECT_EQ(nullptr, overrideBuffer2);
578     EXPECT_EQ(nullptr, overrideBuffer3);
579 
580     // This time we merge the CachedSet in, so we have a new hash, and we should
581     // only have two sets.
582     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _, _, _)).Times(0);
583     initializeOverrideBuffer(layers);
584     EXPECT_NE(getNonBufferHash(layers),
585               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
586     mFlattener->renderCachedSets(mOutputState, std::nullopt);
587 
588     EXPECT_NE(nullptr, overrideBuffer1);
589     EXPECT_EQ(overrideBuffer1, overrideBuffer2);
590     EXPECT_EQ(nullptr, overrideBuffer3);
591 }
592 
TEST_F(FlattenerTest,flattenLayers_pip)593 TEST_F(FlattenerTest, flattenLayers_pip) {
594     mTestLayers[0]->outputLayerCompositionState.displayFrame = Rect(0, 0, 5, 5);
595     auto& layerState1 = mTestLayers[0]->layerState;
596     const auto& overrideBuffer1 = layerState1->getOutputLayer()->getState().overrideInfo.buffer;
597 
598     auto& layerState2 = mTestLayers[1]->layerState;
599     const auto& overrideBuffer2 = layerState2->getOutputLayer()->getState().overrideInfo.buffer;
600 
601     auto& layerState3 = mTestLayers[2]->layerState;
602     const auto& overrideBuffer3 = layerState3->getOutputLayer()->getState().overrideInfo.buffer;
603 
604     EXPECT_CALL(*mTestLayers[2]->layerFE, hasRoundedCorners()).WillRepeatedly(Return(true));
605 
606     std::vector<LayerFE::LayerSettings> clientCompositionList = {
607             LayerFE::LayerSettings{},
608     };
609     clientCompositionList[0].source.buffer.buffer = std::make_shared<
610             renderengine::ExternalTexture>(mTestLayers[2]->layerFECompositionState.buffer,
611                                            mRenderEngine,
612                                            renderengine::ExternalTexture::Usage::READABLE);
613     EXPECT_CALL(*mTestLayers[2]->layerFE, prepareClientCompositionList(_))
614             .WillOnce(Return(clientCompositionList));
615 
616     const std::vector<const LayerState*> layers = {
617             layerState1.get(),
618             layerState2.get(),
619             layerState3.get(),
620     };
621 
622     initializeFlattener(layers);
623 
624     // 3 has a buffer update, so it will not be merged, and it has round
625     // corners, so it is a PIP.
626     mTime += 200ms;
627     layerState3->resetFramesSinceBufferUpdate();
628 
629     initializeOverrideBuffer(layers);
630     EXPECT_EQ(getNonBufferHash(layers),
631               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
632 
633     // This will render a CachedSet.
634     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _, _, _)).WillOnce(Return(NO_ERROR));
635     mFlattener->renderCachedSets(mOutputState, std::nullopt);
636 
637     // We've rendered a CachedSet, but we haven't merged it in.
638     EXPECT_EQ(nullptr, overrideBuffer1);
639     EXPECT_EQ(nullptr, overrideBuffer2);
640     EXPECT_EQ(nullptr, overrideBuffer3);
641 
642     // This time we merge the CachedSet in, so we have a new hash, and we should
643     // only have two sets.
644     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _, _, _)).Times(0);
645     initializeOverrideBuffer(layers);
646     EXPECT_NE(getNonBufferHash(layers),
647               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
648     mFlattener->renderCachedSets(mOutputState, std::nullopt);
649 
650     EXPECT_NE(nullptr, overrideBuffer1);
651     EXPECT_EQ(overrideBuffer1, overrideBuffer2);
652     EXPECT_EQ(nullptr, overrideBuffer3);
653 
654     const auto* peekThroughLayer1 =
655             layerState1->getOutputLayer()->getState().overrideInfo.peekThroughLayer;
656     const auto* peekThroughLayer2 =
657             layerState2->getOutputLayer()->getState().overrideInfo.peekThroughLayer;
658     EXPECT_EQ(&mTestLayers[2]->outputLayer, peekThroughLayer1);
659     EXPECT_EQ(peekThroughLayer1, peekThroughLayer2);
660 }
661 
TEST_F(FlattenerTest,flattenLayers_flattensBlurBehindRunIfFirstRun)662 TEST_F(FlattenerTest, flattenLayers_flattensBlurBehindRunIfFirstRun) {
663     auto& layerState1 = mTestLayers[0]->layerState;
664 
665     auto& layerState2 = mTestLayers[1]->layerState;
666     mTestLayers[1]->layerFECompositionState.backgroundBlurRadius = 1;
667     layerState2->update(&mTestLayers[1]->outputLayer);
668 
669     auto& layerState3 = mTestLayers[2]->layerState;
670     const auto& overrideBuffer1 = layerState1->getOutputLayer()->getState().overrideInfo.buffer;
671     const auto& overrideBuffer2 = layerState2->getOutputLayer()->getState().overrideInfo.buffer;
672     const auto& overrideBuffer3 = layerState3->getOutputLayer()->getState().overrideInfo.buffer;
673 
674     const std::vector<const LayerState*> layers = {
675             layerState1.get(),
676             layerState2.get(),
677             layerState3.get(),
678     };
679 
680     initializeFlattener(layers);
681 
682     // Mark the first two layers inactive, which contain the blur behind
683     mTime += 200ms;
684     layerState3->resetFramesSinceBufferUpdate();
685 
686     // layers would be flattened but the buffer would not be overridden
687     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _, _, _)).WillOnce(Return(NO_ERROR));
688 
689     initializeOverrideBuffer(layers);
690     EXPECT_EQ(getNonBufferHash(layers),
691               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
692     mFlattener->renderCachedSets(mOutputState, std::nullopt);
693 
694     for (const auto layer : layers) {
695         EXPECT_EQ(nullptr, layer->getOutputLayer()->getState().overrideInfo.buffer);
696     }
697 
698     // the new flattened layer is replaced
699     initializeOverrideBuffer(layers);
700     EXPECT_NE(getNonBufferHash(layers),
701               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
702     mFlattener->renderCachedSets(mOutputState, std::nullopt);
703     EXPECT_NE(nullptr, overrideBuffer1);
704     EXPECT_EQ(overrideBuffer1, overrideBuffer2);
705     EXPECT_EQ(nullptr, overrideBuffer3);
706 }
707 
TEST_F(FlattenerTest,flattenLayers_doesNotFlattenBlurBehindRun)708 TEST_F(FlattenerTest, flattenLayers_doesNotFlattenBlurBehindRun) {
709     auto& layerState1 = mTestLayers[0]->layerState;
710 
711     auto& layerState2 = mTestLayers[1]->layerState;
712     mTestLayers[1]->layerFECompositionState.backgroundBlurRadius = 1;
713     layerState2->update(&mTestLayers[1]->outputLayer);
714 
715     auto& layerState3 = mTestLayers[2]->layerState;
716 
717     const std::vector<const LayerState*> layers = {
718             layerState1.get(),
719             layerState2.get(),
720             layerState3.get(),
721     };
722 
723     initializeFlattener(layers);
724 
725     // Mark the last two layers inactive, which contains the blur layer, but does not contain the
726     // first layer
727     mTime += 200ms;
728     layerState1->resetFramesSinceBufferUpdate();
729 
730     // layers would be flattened but the buffer would not be overridden
731     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _, _, _)).WillRepeatedly(Return(NO_ERROR));
732 
733     initializeOverrideBuffer(layers);
734     EXPECT_EQ(getNonBufferHash(layers),
735               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
736     mFlattener->renderCachedSets(mOutputState, std::nullopt);
737 
738     for (const auto layer : layers) {
739         EXPECT_EQ(nullptr, layer->getOutputLayer()->getState().overrideInfo.buffer);
740     }
741 
742     // nothing is flattened because the last two frames cannot be cached due to containing a blur
743     // layer
744     initializeOverrideBuffer(layers);
745     EXPECT_EQ(getNonBufferHash(layers),
746               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
747     mFlattener->renderCachedSets(mOutputState, std::nullopt);
748     for (const auto layer : layers) {
749         EXPECT_EQ(nullptr, layer->getOutputLayer()->getState().overrideInfo.buffer);
750     }
751 }
752 
TEST_F(FlattenerTest,flattenLayers_flattenSkipsLayerWithBlurBehind)753 TEST_F(FlattenerTest, flattenLayers_flattenSkipsLayerWithBlurBehind) {
754     auto& layerState1 = mTestLayers[0]->layerState;
755 
756     auto& layerStateWithBlurBehind = mTestLayers[1]->layerState;
757     mTestLayers[1]->layerFECompositionState.backgroundBlurRadius = 1;
758     layerStateWithBlurBehind->update(&mTestLayers[1]->outputLayer);
759 
760     auto& layerState3 = mTestLayers[2]->layerState;
761     auto& layerState4 = mTestLayers[3]->layerState;
762     const auto& overrideBuffer1 = layerState1->getOutputLayer()->getState().overrideInfo.buffer;
763     const auto& blurOverrideBuffer =
764             layerStateWithBlurBehind->getOutputLayer()->getState().overrideInfo.buffer;
765     const auto& overrideBuffer3 = layerState3->getOutputLayer()->getState().overrideInfo.buffer;
766     const auto& overrideBuffer4 = layerState4->getOutputLayer()->getState().overrideInfo.buffer;
767 
768     const std::vector<const LayerState*> layers = {
769             layerState1.get(),
770             layerStateWithBlurBehind.get(),
771             layerState3.get(),
772             layerState4.get(),
773     };
774 
775     initializeFlattener(layers);
776 
777     // Mark the last three layers inactive, which contains the blur layer, but does not contain the
778     // first layer
779     mTime += 200ms;
780     layerState1->resetFramesSinceBufferUpdate();
781 
782     // layers would be flattened but the buffer would not be overridden
783     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _, _, _)).WillOnce(Return(NO_ERROR));
784 
785     initializeOverrideBuffer(layers);
786     EXPECT_EQ(getNonBufferHash(layers),
787               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
788     mFlattener->renderCachedSets(mOutputState, std::nullopt);
789 
790     for (const auto layer : layers) {
791         EXPECT_EQ(nullptr, layer->getOutputLayer()->getState().overrideInfo.buffer);
792     }
793 
794     // the new flattened layer is replaced
795     initializeOverrideBuffer(layers);
796     EXPECT_NE(getNonBufferHash(layers),
797               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
798     mFlattener->renderCachedSets(mOutputState, std::nullopt);
799     EXPECT_EQ(nullptr, overrideBuffer1);
800     EXPECT_EQ(nullptr, blurOverrideBuffer);
801     EXPECT_NE(nullptr, overrideBuffer3);
802     EXPECT_EQ(overrideBuffer3, overrideBuffer4);
803 }
804 
TEST_F(FlattenerTest,flattenLayers_whenBlurLayerIsChanging_appliesBlurToInactiveBehindLayers)805 TEST_F(FlattenerTest, flattenLayers_whenBlurLayerIsChanging_appliesBlurToInactiveBehindLayers) {
806     auto& layerState1 = mTestLayers[0]->layerState;
807     auto& layerState2 = mTestLayers[1]->layerState;
808 
809     auto& layerStateWithBlurBehind = mTestLayers[2]->layerState;
810     mTestLayers[2]->layerFECompositionState.backgroundBlurRadius = 1;
811     layerStateWithBlurBehind->update(&mTestLayers[2]->outputLayer);
812     const auto& overrideBuffer1 = layerState1->getOutputLayer()->getState().overrideInfo.buffer;
813     const auto& overrideBuffer2 = layerState2->getOutputLayer()->getState().overrideInfo.buffer;
814     const auto& blurOverrideBuffer =
815             layerStateWithBlurBehind->getOutputLayer()->getState().overrideInfo.buffer;
816 
817     const std::vector<const LayerState*> layers = {
818             layerState1.get(),
819             layerState2.get(),
820             layerStateWithBlurBehind.get(),
821     };
822 
823     initializeFlattener(layers);
824 
825     // Mark the first two layers inactive, but update the blur layer
826     mTime += 200ms;
827     layerStateWithBlurBehind->resetFramesSinceBufferUpdate();
828 
829     // layers would be flattened but the buffer would not be overridden
830     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _, _, _)).WillOnce(Return(NO_ERROR));
831 
832     initializeOverrideBuffer(layers);
833     EXPECT_EQ(getNonBufferHash(layers),
834               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
835     mFlattener->renderCachedSets(mOutputState, std::nullopt);
836 
837     const auto& cachedSet = mFlattener->getNewCachedSetForTesting();
838     ASSERT_NE(std::nullopt, cachedSet);
839     EXPECT_EQ(&mTestLayers[2]->outputLayer, cachedSet->getBlurLayer());
840 
841     for (const auto layer : layers) {
842         EXPECT_EQ(nullptr, layer->getOutputLayer()->getState().overrideInfo.buffer);
843     }
844 
845     // the new flattened layer is replaced
846     initializeOverrideBuffer(layers);
847     EXPECT_NE(getNonBufferHash(layers),
848               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
849     mFlattener->renderCachedSets(mOutputState, std::nullopt);
850     EXPECT_NE(nullptr, overrideBuffer1);
851     EXPECT_EQ(overrideBuffer2, overrideBuffer1);
852     EXPECT_EQ(nullptr, blurOverrideBuffer);
853 }
854 
TEST_F(FlattenerTest,flattenLayers_renderCachedSets_doesNotRenderTwice)855 TEST_F(FlattenerTest, flattenLayers_renderCachedSets_doesNotRenderTwice) {
856     auto& layerState1 = mTestLayers[0]->layerState;
857     auto& layerState2 = mTestLayers[1]->layerState;
858     const auto& overrideBuffer1 = layerState1->getOutputLayer()->getState().overrideInfo.buffer;
859     const auto& overrideBuffer2 = layerState2->getOutputLayer()->getState().overrideInfo.buffer;
860 
861     const std::vector<const LayerState*> layers = {
862             layerState1.get(),
863             layerState2.get(),
864     };
865 
866     initializeFlattener(layers);
867 
868     // Mark the layers inactive
869     mTime += 200ms;
870     // layers would be flattened but the buffer would not be overridden
871     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _, _, _)).WillOnce(Return(NO_ERROR));
872 
873     initializeOverrideBuffer(layers);
874     EXPECT_EQ(getNonBufferHash(layers),
875               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
876     mFlattener->renderCachedSets(mOutputState, std::nullopt);
877 
878     EXPECT_EQ(nullptr, overrideBuffer1);
879     EXPECT_EQ(nullptr, overrideBuffer2);
880 
881     // Simulate attempting to render prior to merging the new cached set with the layer stack.
882     // Here we should not try to re-render.
883     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _, _, _)).Times(0);
884     mFlattener->renderCachedSets(mOutputState, std::nullopt);
885 
886     // We provide the override buffer now that it's rendered
887     EXPECT_NE(getNonBufferHash(layers),
888               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
889     mFlattener->renderCachedSets(mOutputState, std::nullopt);
890 
891     EXPECT_NE(nullptr, overrideBuffer1);
892     EXPECT_EQ(overrideBuffer2, overrideBuffer1);
893 }
894 
895 const constexpr std::chrono::nanoseconds kCachedSetRenderDuration = 0ms;
896 const constexpr size_t kMaxDeferRenderAttempts = 2;
897 
898 class FlattenerRenderSchedulingTest : public FlattenerTest {
899 public:
FlattenerRenderSchedulingTest()900     FlattenerRenderSchedulingTest()
901           : FlattenerTest(
902                     Flattener::CachedSetRenderSchedulingTunables{.cachedSetRenderDuration =
903                                                                          kCachedSetRenderDuration,
904                                                                  .maxDeferRenderAttempts =
905                                                                          kMaxDeferRenderAttempts}) {
906     }
907 };
908 
TEST_F(FlattenerRenderSchedulingTest,flattenLayers_renderCachedSets_defersUpToMaxAttempts)909 TEST_F(FlattenerRenderSchedulingTest, flattenLayers_renderCachedSets_defersUpToMaxAttempts) {
910     auto& layerState1 = mTestLayers[0]->layerState;
911     auto& layerState2 = mTestLayers[1]->layerState;
912 
913     const std::vector<const LayerState*> layers = {
914             layerState1.get(),
915             layerState2.get(),
916     };
917 
918     initializeFlattener(layers);
919 
920     // Mark the layers inactive
921     mTime += 200ms;
922 
923     initializeOverrideBuffer(layers);
924     EXPECT_EQ(getNonBufferHash(layers),
925               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
926 
927     for (size_t i = 0; i < kMaxDeferRenderAttempts; i++) {
928         EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _, _, _)).Times(0);
929         mFlattener->renderCachedSets(mOutputState,
930                                      std::chrono::steady_clock::now() -
931                                              (kCachedSetRenderDuration + 10ms));
932     }
933 
934     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _, _, _)).WillOnce(Return(NO_ERROR));
935     mFlattener->renderCachedSets(mOutputState,
936                                  std::chrono::steady_clock::now() -
937                                          (kCachedSetRenderDuration + 10ms));
938 }
939 
TEST_F(FlattenerTest,flattenLayers_skipsBT601_625)940 TEST_F(FlattenerTest, flattenLayers_skipsBT601_625) {
941     auto& layerState1 = mTestLayers[0]->layerState;
942     const auto& overrideBuffer1 = layerState1->getOutputLayer()->getState().overrideInfo.buffer;
943 
944     auto& layerState2 = mTestLayers[1]->layerState;
945     const auto& overrideBuffer2 = layerState2->getOutputLayer()->getState().overrideInfo.buffer;
946 
947     // The third layer uses a dataspace that will not be flattened due to
948     // possible mismatch with DPU rendering.
949     auto& layerState3 = mTestLayers[2]->layerState;
950     const auto& overrideBuffer3 = layerState3->getOutputLayer()->getState().overrideInfo.buffer;
951     mTestLayers[2]->outputLayerCompositionState.dataspace = ui::Dataspace::STANDARD_BT601_625;
952     mTestLayers[2]->layerState->update(&mTestLayers[2]->outputLayer);
953 
954     const std::vector<const LayerState*> layers = {
955             layerState1.get(),
956             layerState2.get(),
957             layerState3.get(),
958     };
959 
960     initializeFlattener(layers);
961 
962     mTime += 200ms;
963     initializeOverrideBuffer(layers);
964     EXPECT_EQ(getNonBufferHash(layers),
965               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
966 
967     // This will render a CachedSet.
968     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _, _, _)).WillOnce(Return(NO_ERROR));
969     mFlattener->renderCachedSets(mOutputState, std::nullopt);
970 
971     // We've rendered a CachedSet, but we haven't merged it in.
972     EXPECT_EQ(nullptr, overrideBuffer1);
973     EXPECT_EQ(nullptr, overrideBuffer2);
974     EXPECT_EQ(nullptr, overrideBuffer3);
975 
976     // This time we merge the CachedSet in, so we have a new hash, and we should
977     // only have two sets.
978     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _, _, _)).Times(0);
979     initializeOverrideBuffer(layers);
980     EXPECT_NE(getNonBufferHash(layers),
981               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
982     mFlattener->renderCachedSets(mOutputState, std::nullopt);
983 
984     EXPECT_NE(nullptr, overrideBuffer1);
985     EXPECT_EQ(overrideBuffer1, overrideBuffer2);
986     EXPECT_EQ(nullptr, overrideBuffer3);
987 }
988 
TEST_F(FlattenerTest,flattenLayers_skipsHDR)989 TEST_F(FlattenerTest, flattenLayers_skipsHDR) {
990     auto& layerState1 = mTestLayers[0]->layerState;
991     const auto& overrideBuffer1 = layerState1->getOutputLayer()->getState().overrideInfo.buffer;
992 
993     auto& layerState2 = mTestLayers[1]->layerState;
994     const auto& overrideBuffer2 = layerState2->getOutputLayer()->getState().overrideInfo.buffer;
995 
996     // The third layer uses a dataspace that will not be flattened due to
997     // possible mismatch with DPU rendering.
998     auto& layerState3 = mTestLayers[2]->layerState;
999     const auto& overrideBuffer3 = layerState3->getOutputLayer()->getState().overrideInfo.buffer;
1000     mTestLayers[2]->outputLayerCompositionState.dataspace = ui::Dataspace::BT2020_ITU_HLG;
1001     mTestLayers[2]->layerState->update(&mTestLayers[2]->outputLayer);
1002 
1003     const std::vector<const LayerState*> layers = {
1004             layerState1.get(),
1005             layerState2.get(),
1006             layerState3.get(),
1007     };
1008 
1009     initializeFlattener(layers);
1010 
1011     mTime += 200ms;
1012     initializeOverrideBuffer(layers);
1013     EXPECT_EQ(getNonBufferHash(layers),
1014               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
1015 
1016     // This will render a CachedSet.
1017     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _, _, _)).WillOnce(Return(NO_ERROR));
1018     mFlattener->renderCachedSets(mOutputState, std::nullopt);
1019 
1020     // We've rendered a CachedSet, but we haven't merged it in.
1021     EXPECT_EQ(nullptr, overrideBuffer1);
1022     EXPECT_EQ(nullptr, overrideBuffer2);
1023     EXPECT_EQ(nullptr, overrideBuffer3);
1024 
1025     // This time we merge the CachedSet in, so we have a new hash, and we should
1026     // only have two sets.
1027     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _, _, _)).Times(0);
1028     initializeOverrideBuffer(layers);
1029     EXPECT_NE(getNonBufferHash(layers),
1030               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
1031     mFlattener->renderCachedSets(mOutputState, std::nullopt);
1032 
1033     EXPECT_NE(nullptr, overrideBuffer1);
1034     EXPECT_EQ(overrideBuffer1, overrideBuffer2);
1035     EXPECT_EQ(nullptr, overrideBuffer3);
1036 }
1037 
TEST_F(FlattenerTest,flattenLayers_skipsHDR2)1038 TEST_F(FlattenerTest, flattenLayers_skipsHDR2) {
1039     auto& layerState1 = mTestLayers[0]->layerState;
1040     const auto& overrideBuffer1 = layerState1->getOutputLayer()->getState().overrideInfo.buffer;
1041 
1042     auto& layerState2 = mTestLayers[1]->layerState;
1043     const auto& overrideBuffer2 = layerState2->getOutputLayer()->getState().overrideInfo.buffer;
1044 
1045     // The third layer uses a dataspace that will not be flattened due to
1046     // possible mismatch with DPU rendering.
1047     auto& layerState3 = mTestLayers[2]->layerState;
1048     const auto& overrideBuffer3 = layerState3->getOutputLayer()->getState().overrideInfo.buffer;
1049     mTestLayers[2]->outputLayerCompositionState.dataspace = ui::Dataspace::BT2020_PQ;
1050     mTestLayers[2]->layerState->update(&mTestLayers[2]->outputLayer);
1051 
1052     const std::vector<const LayerState*> layers = {
1053             layerState1.get(),
1054             layerState2.get(),
1055             layerState3.get(),
1056     };
1057 
1058     initializeFlattener(layers);
1059 
1060     mTime += 200ms;
1061     initializeOverrideBuffer(layers);
1062     EXPECT_EQ(getNonBufferHash(layers),
1063               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
1064 
1065     // This will render a CachedSet.
1066     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _, _, _)).WillOnce(Return(NO_ERROR));
1067     mFlattener->renderCachedSets(mOutputState, std::nullopt);
1068 
1069     // We've rendered a CachedSet, but we haven't merged it in.
1070     EXPECT_EQ(nullptr, overrideBuffer1);
1071     EXPECT_EQ(nullptr, overrideBuffer2);
1072     EXPECT_EQ(nullptr, overrideBuffer3);
1073 
1074     // This time we merge the CachedSet in, so we have a new hash, and we should
1075     // only have two sets.
1076     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _, _, _)).Times(0);
1077     initializeOverrideBuffer(layers);
1078     EXPECT_NE(getNonBufferHash(layers),
1079               mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
1080     mFlattener->renderCachedSets(mOutputState, std::nullopt);
1081 
1082     EXPECT_NE(nullptr, overrideBuffer1);
1083     EXPECT_EQ(overrideBuffer1, overrideBuffer2);
1084     EXPECT_EQ(nullptr, overrideBuffer3);
1085 }
1086 
1087 } // namespace
1088 } // namespace android::compositionengine
1089