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