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