• 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/LayerState.h>
20 #include <compositionengine/mock/LayerFE.h>
21 #include <compositionengine/mock/OutputLayer.h>
22 #include <gmock/gmock-actions.h>
23 #include <gtest/gtest.h>
24 #include <renderengine/ExternalTexture.h>
25 #include <renderengine/mock/FakeExternalTexture.h>
26 #include <renderengine/mock/RenderEngine.h>
27 #include <ui/GraphicTypes.h>
28 #include <utils/Errors.h>
29 #include <memory>
30 
31 #include "tests/TestUtils.h"
32 
33 namespace android::compositionengine {
34 using namespace std::chrono_literals;
35 
36 using testing::_;
37 using testing::DoAll;
38 using testing::Invoke;
39 using testing::Return;
40 using testing::ReturnRef;
41 using testing::SetArgPointee;
42 
43 using impl::planner::CachedSet;
44 using impl::planner::LayerState;
45 using impl::planner::LayerStateField;
46 using impl::planner::TexturePool;
47 
48 namespace {
49 
50 MATCHER_P(ClientCompositionTargetSettingsBlurSettingsEq, expectedBlurSetting, "") {
51     *result_listener << "ClientCompositionTargetSettings' BlurSettings aren't equal \n";
52     *result_listener << "expected " << expectedBlurSetting << "\n";
53     *result_listener << "actual " << arg.blurSetting << "\n";
54 
55     return expectedBlurSetting == arg.blurSetting;
56 }
57 
58 MATCHER_P(ClientCompositionTargetSettingsSecureEq, expectedSecureSetting, "") {
59     *result_listener << "ClientCompositionTargetSettings' isSecure bits aren't equal \n";
60     *result_listener << "expected " << expectedSecureSetting << "\n";
61     *result_listener << "actual " << arg.isSecure << "\n";
62 
63     return expectedSecureSetting == arg.isSecure;
64 }
65 
66 MATCHER_P(ClientCompositionTargetSettingsWhitePointEq, expectedWhitePoint, "") {
67     *result_listener << "ClientCompositionTargetSettings' white points aren't equal \n";
68     *result_listener << "expected " << expectedWhitePoint << "\n";
69     *result_listener << "actual " << arg.whitePointNits << "\n";
70 
71     return expectedWhitePoint == arg.whitePointNits;
72 }
73 
74 static const ui::Size kOutputSize = ui::Size(1, 1);
75 
76 class CachedSetTest : public testing::Test {
77 public:
78     CachedSetTest() = default;
79     void SetUp() override;
80     void TearDown() override;
81 
82 protected:
83     const std::chrono::steady_clock::time_point kStartTime = std::chrono::steady_clock::now();
84 
85     struct TestLayer {
86         mock::OutputLayer outputLayer;
87         impl::OutputLayerCompositionState outputLayerCompositionState;
88         // LayerFE inherits from RefBase and must be held by an sp<>
89         sp<mock::LayerFE> layerFE;
90         LayerFECompositionState layerFECompositionState;
91 
92         std::unique_ptr<LayerState> layerState;
93         std::unique_ptr<CachedSet::Layer> cachedSetLayer;
94     };
95 
96     static constexpr size_t kNumLayers = 5;
97     std::vector<std::unique_ptr<TestLayer>> mTestLayers;
98     impl::OutputCompositionState mOutputState;
99 
100     android::renderengine::mock::RenderEngine mRenderEngine;
101     TexturePool mTexturePool = TexturePool(mRenderEngine);
102 };
103 
SetUp()104 void CachedSetTest::SetUp() {
105     mTexturePool.setDisplaySize(kOutputSize);
106     for (size_t i = 0; i < kNumLayers; i++) {
107         auto testLayer = std::make_unique<TestLayer>();
108         auto pos = static_cast<int32_t>(i);
109         testLayer->outputLayerCompositionState.displayFrame = Rect(pos, pos, pos + 1, pos + 1);
110         testLayer->outputLayerCompositionState.visibleRegion =
111                 Region(Rect(pos + 1, pos + 1, pos + 2, pos + 2));
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).WillRepeatedly(Return("testLayer"));
118         EXPECT_CALL(*testLayer->layerFE, getCompositionState)
119                 .WillRepeatedly(Return(&testLayer->layerFECompositionState));
120         EXPECT_CALL(testLayer->outputLayer, getLayerFE)
121                 .WillRepeatedly(ReturnRef(*testLayer->layerFE));
122         EXPECT_CALL(testLayer->outputLayer, getState)
123                 .WillRepeatedly(ReturnRef(testLayer->outputLayerCompositionState));
124 
125         testLayer->layerState = std::make_unique<LayerState>(&testLayer->outputLayer);
126         testLayer->layerState->incrementFramesSinceBufferUpdate();
127         testLayer->cachedSetLayer =
128                 std::make_unique<CachedSet::Layer>(testLayer->layerState.get(), kStartTime);
129 
130         mTestLayers.emplace_back(std::move(testLayer));
131 
132         // set up minimium params needed for rendering
133         mOutputState.dataspace = ui::Dataspace::SRGB;
134         mOutputState.framebufferSpace = ProjectionSpace(ui::Size(10, 20), Rect(10, 5));
135         mOutputState.framebufferSpace.setOrientation(ui::ROTATION_90);
136         mOutputState.layerStackSpace = ProjectionSpace(ui::Size(20, 10), Rect(5, 10));
137     }
138 }
139 
TearDown()140 void CachedSetTest::TearDown() {
141     mTestLayers.clear();
142 }
143 
expectEqual(const CachedSet & cachedSet,const CachedSet::Layer & layer)144 void expectEqual(const CachedSet& cachedSet, const CachedSet::Layer& layer) {
145     EXPECT_EQ(layer.getLastUpdate(), cachedSet.getLastUpdate());
146     EXPECT_EQ(layer.getDisplayFrame(), cachedSet.getBounds());
147     EXPECT_TRUE(layer.getVisibleRegion().hasSameRects(cachedSet.getVisibleRegion()));
148     EXPECT_EQ(1u, cachedSet.getLayerCount());
149     EXPECT_EQ(layer.getState(), cachedSet.getFirstLayer().getState());
150     EXPECT_EQ(0u, cachedSet.getAge());
151     EXPECT_EQ(layer.getHash(), cachedSet.getNonBufferHash());
152 }
153 
expectEqual(const CachedSet & cachedSet,const LayerState & layerState,std::chrono::steady_clock::time_point lastUpdate)154 void expectEqual(const CachedSet& cachedSet, const LayerState& layerState,
155                  std::chrono::steady_clock::time_point lastUpdate) {
156     CachedSet::Layer layer(&layerState, lastUpdate);
157     expectEqual(cachedSet, layer);
158 }
159 
expectNoBuffer(const CachedSet & cachedSet)160 void expectNoBuffer(const CachedSet& cachedSet) {
161     EXPECT_EQ(nullptr, cachedSet.getBuffer());
162     EXPECT_EQ(nullptr, cachedSet.getDrawFence());
163     EXPECT_FALSE(cachedSet.hasReadyBuffer());
164 }
165 
expectReadyBuffer(const CachedSet & cachedSet)166 void expectReadyBuffer(const CachedSet& cachedSet) {
167     EXPECT_NE(nullptr, cachedSet.getBuffer());
168     EXPECT_NE(nullptr, cachedSet.getDrawFence());
169     EXPECT_TRUE(cachedSet.hasReadyBuffer());
170     EXPECT_TRUE(cachedSet.hasRenderedBuffer());
171 }
172 
TEST_F(CachedSetTest,createFromLayer)173 TEST_F(CachedSetTest, createFromLayer) {
174     CachedSet::Layer& layer = *mTestLayers[0]->cachedSetLayer.get();
175     CachedSet cachedSet(layer);
176     expectEqual(cachedSet, layer);
177     expectNoBuffer(cachedSet);
178 }
179 
TEST_F(CachedSetTest,createFromLayerState)180 TEST_F(CachedSetTest, createFromLayerState) {
181     LayerState& layerState = *mTestLayers[0]->layerState.get();
182     CachedSet cachedSet(&layerState, kStartTime);
183     expectEqual(cachedSet, layerState, kStartTime);
184     expectNoBuffer(cachedSet);
185 }
186 
TEST_F(CachedSetTest,addLayer)187 TEST_F(CachedSetTest, addLayer) {
188     CachedSet::Layer& layer1 = *mTestLayers[0]->cachedSetLayer.get();
189     CachedSet::Layer& layer2 = *mTestLayers[1]->cachedSetLayer.get();
190 
191     CachedSet cachedSet(layer1);
192     cachedSet.addLayer(layer2.getState(), kStartTime + 10ms);
193 
194     EXPECT_EQ(kStartTime, cachedSet.getLastUpdate());
195     EXPECT_EQ(Rect(0, 0, 2, 2), cachedSet.getBounds());
196     Region expectedRegion;
197     expectedRegion.orSelf(Rect(1, 1, 2, 2));
198     expectedRegion.orSelf(Rect(2, 2, 3, 3));
199     EXPECT_TRUE(cachedSet.getVisibleRegion().hasSameRects(expectedRegion));
200     EXPECT_EQ(2u, cachedSet.getLayerCount());
201     EXPECT_EQ(0u, cachedSet.getAge());
202     expectNoBuffer(cachedSet);
203     // TODO(b/181192080): check that getNonBufferHash returns the correct hash value
204     // EXPECT_EQ(android::hashCombine(layer1.getHash(), layer2.getHash()),
205     // cachedSet.getNonBufferHash());
206 }
207 
TEST_F(CachedSetTest,decompose)208 TEST_F(CachedSetTest, decompose) {
209     CachedSet::Layer& layer1 = *mTestLayers[0]->cachedSetLayer.get();
210     CachedSet::Layer& layer2 = *mTestLayers[1]->cachedSetLayer.get();
211     CachedSet::Layer& layer3 = *mTestLayers[2]->cachedSetLayer.get();
212 
213     CachedSet cachedSet(layer1);
214     cachedSet.addLayer(layer2.getState(), kStartTime + 10ms);
215     cachedSet.addLayer(layer3.getState(), kStartTime + 20ms);
216 
217     std::vector<CachedSet> decomposed = cachedSet.decompose();
218     EXPECT_EQ(3u, decomposed.size());
219     expectEqual(decomposed[0], *layer1.getState(), kStartTime);
220     expectNoBuffer(decomposed[0]);
221 
222     expectEqual(decomposed[1], *layer2.getState(), kStartTime + 10ms);
223     expectNoBuffer(decomposed[1]);
224 
225     expectEqual(decomposed[2], *layer3.getState(), kStartTime + 20ms);
226     expectNoBuffer(decomposed[2]);
227 }
228 
TEST_F(CachedSetTest,setLastUpdate)229 TEST_F(CachedSetTest, setLastUpdate) {
230     LayerState& layerState = *mTestLayers[0]->layerState.get();
231     CachedSet cachedSet(&layerState, kStartTime);
232     cachedSet.setLastUpdate(kStartTime + 10ms);
233     expectEqual(cachedSet, layerState, kStartTime + 10ms);
234 }
235 
TEST_F(CachedSetTest,incrementAge)236 TEST_F(CachedSetTest, incrementAge) {
237     CachedSet::Layer& layer = *mTestLayers[0]->cachedSetLayer.get();
238     CachedSet cachedSet(layer);
239     EXPECT_EQ(0u, cachedSet.getAge());
240     cachedSet.incrementAge();
241     EXPECT_EQ(1u, cachedSet.getAge());
242     cachedSet.incrementAge();
243     EXPECT_EQ(2u, cachedSet.getAge());
244 }
245 
TEST_F(CachedSetTest,incrementSkipCount)246 TEST_F(CachedSetTest, incrementSkipCount) {
247     CachedSet::Layer& layer = *mTestLayers[0]->cachedSetLayer.get();
248     CachedSet cachedSet(layer);
249     EXPECT_EQ(0u, cachedSet.getSkipCount());
250     cachedSet.incrementSkipCount();
251     EXPECT_EQ(1u, cachedSet.getSkipCount());
252     cachedSet.incrementSkipCount();
253     EXPECT_EQ(2u, cachedSet.getSkipCount());
254 }
255 
TEST_F(CachedSetTest,hasBufferUpdate_NoUpdate)256 TEST_F(CachedSetTest, hasBufferUpdate_NoUpdate) {
257     CachedSet::Layer& layer1 = *mTestLayers[0]->cachedSetLayer.get();
258     CachedSet::Layer& layer2 = *mTestLayers[1]->cachedSetLayer.get();
259     CachedSet::Layer& layer3 = *mTestLayers[2]->cachedSetLayer.get();
260 
261     CachedSet cachedSet(layer1);
262     cachedSet.addLayer(layer2.getState(), kStartTime + 10ms);
263     cachedSet.addLayer(layer3.getState(), kStartTime + 20ms);
264 
265     EXPECT_FALSE(cachedSet.hasBufferUpdate());
266 }
267 
TEST_F(CachedSetTest,hasBufferUpdate_BufferUpdate)268 TEST_F(CachedSetTest, hasBufferUpdate_BufferUpdate) {
269     CachedSet::Layer& layer1 = *mTestLayers[0]->cachedSetLayer.get();
270     CachedSet::Layer& layer2 = *mTestLayers[1]->cachedSetLayer.get();
271     CachedSet::Layer& layer3 = *mTestLayers[2]->cachedSetLayer.get();
272 
273     CachedSet cachedSet(layer1);
274     cachedSet.addLayer(layer2.getState(), kStartTime + 10ms);
275     cachedSet.addLayer(layer3.getState(), kStartTime + 20ms);
276 
277     mTestLayers[1]->layerState->resetFramesSinceBufferUpdate();
278 
279     EXPECT_TRUE(cachedSet.hasBufferUpdate());
280 }
281 
TEST_F(CachedSetTest,append)282 TEST_F(CachedSetTest, append) {
283     CachedSet::Layer& layer1 = *mTestLayers[0]->cachedSetLayer.get();
284     CachedSet::Layer& layer2 = *mTestLayers[1]->cachedSetLayer.get();
285     CachedSet::Layer& layer3 = *mTestLayers[2]->cachedSetLayer.get();
286 
287     CachedSet cachedSet1(layer1);
288     CachedSet cachedSet2(layer2);
289     cachedSet1.addLayer(layer3.getState(), kStartTime + 10ms);
290     cachedSet1.incrementSkipCount();
291     EXPECT_EQ(1u, cachedSet1.getSkipCount());
292     cachedSet1.append(cachedSet2);
293 
294     EXPECT_EQ(kStartTime, cachedSet1.getLastUpdate());
295     EXPECT_EQ(Rect(0, 0, 3, 3), cachedSet1.getBounds());
296     Region expectedRegion;
297     expectedRegion.orSelf(Rect(1, 1, 2, 2));
298     expectedRegion.orSelf(Rect(2, 2, 3, 3));
299     expectedRegion.orSelf(Rect(3, 3, 4, 4));
300     EXPECT_TRUE(cachedSet1.getVisibleRegion().hasSameRects(expectedRegion));
301     EXPECT_EQ(3u, cachedSet1.getLayerCount());
302     EXPECT_EQ(0u, cachedSet1.getAge());
303     EXPECT_EQ(0u, cachedSet1.getSkipCount());
304 
305     expectNoBuffer(cachedSet1);
306     // TODO(b/181192080): check that getNonBufferHash returns the correct hash value
307     // EXPECT_EQ(android::hashCombine(layer1.getHash(), layer2.getHash()),
308     // cachedSet1.getNonBufferHash());
309 }
310 
TEST_F(CachedSetTest,updateAge_NoUpdate)311 TEST_F(CachedSetTest, updateAge_NoUpdate) {
312     CachedSet::Layer& layer = *mTestLayers[0]->cachedSetLayer.get();
313 
314     CachedSet cachedSet(layer);
315     cachedSet.incrementAge();
316     EXPECT_EQ(kStartTime, cachedSet.getLastUpdate());
317     EXPECT_EQ(1u, cachedSet.getAge());
318 
319     cachedSet.updateAge(kStartTime + 10ms);
320     EXPECT_EQ(kStartTime, cachedSet.getLastUpdate());
321     EXPECT_EQ(1u, cachedSet.getAge());
322 }
323 
TEST_F(CachedSetTest,updateAge_BufferUpdate)324 TEST_F(CachedSetTest, updateAge_BufferUpdate) {
325     CachedSet::Layer& layer = *mTestLayers[0]->cachedSetLayer.get();
326     mTestLayers[0]->layerState->resetFramesSinceBufferUpdate();
327 
328     CachedSet cachedSet(layer);
329     cachedSet.incrementAge();
330     EXPECT_EQ(kStartTime, cachedSet.getLastUpdate());
331     EXPECT_EQ(1u, cachedSet.getAge());
332 
333     cachedSet.updateAge(kStartTime + 10ms);
334     EXPECT_EQ(kStartTime + 10ms, cachedSet.getLastUpdate());
335     EXPECT_EQ(0u, cachedSet.getAge());
336 }
337 
TEST_F(CachedSetTest,renderUnsecureOutput)338 TEST_F(CachedSetTest, renderUnsecureOutput) {
339     // Skip the 0th layer to ensure that the bounding box of the layers is offset from (0, 0)
340     CachedSet::Layer& layer1 = *mTestLayers[1]->cachedSetLayer.get();
341     sp<mock::LayerFE> layerFE1 = mTestLayers[1]->layerFE;
342     CachedSet::Layer& layer2 = *mTestLayers[2]->cachedSetLayer.get();
343     sp<mock::LayerFE> layerFE2 = mTestLayers[2]->layerFE;
344 
345     CachedSet cachedSet(layer1);
346     cachedSet.append(CachedSet(layer2));
347 
348     std::vector<compositionengine::LayerFE::LayerSettings> clientCompList1;
349     clientCompList1.push_back({});
350     clientCompList1[0].alpha = 0.5f;
351 
352     std::vector<compositionengine::LayerFE::LayerSettings> clientCompList2;
353     clientCompList2.push_back({});
354     clientCompList2[0].alpha = 0.75f;
355 
356     const auto drawLayers =
357             [&](const renderengine::DisplaySettings& displaySettings,
358                 const std::vector<renderengine::LayerSettings>& layers,
359                 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
360                 base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> {
361         EXPECT_EQ(mOutputState.framebufferSpace.getContent(), displaySettings.physicalDisplay);
362         EXPECT_EQ(mOutputState.layerStackSpace.getContent(), displaySettings.clip);
363         EXPECT_EQ(ui::Transform::toRotationFlags(mOutputState.framebufferSpace.getOrientation()),
364                   displaySettings.orientation);
365         EXPECT_EQ(0.5f, layers[0].alpha);
366         EXPECT_EQ(0.75f, layers[1].alpha);
367         EXPECT_EQ(ui::Dataspace::SRGB, displaySettings.outputDataspace);
368         return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
369     };
370 
371     EXPECT_CALL(*layerFE1,
372                 prepareClientCompositionList(ClientCompositionTargetSettingsSecureEq(false)))
373             .WillOnce(Return(clientCompList1));
374     EXPECT_CALL(*layerFE2,
375                 prepareClientCompositionList(ClientCompositionTargetSettingsSecureEq(false)))
376             .WillOnce(Return(clientCompList2));
377     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _, _)).WillOnce(Invoke(drawLayers));
378     mOutputState.isSecure = false;
379     cachedSet.render(mRenderEngine, mTexturePool, mOutputState, true);
380     expectReadyBuffer(cachedSet);
381 
382     EXPECT_EQ(mOutputState.framebufferSpace, cachedSet.getOutputSpace());
383     EXPECT_EQ(Rect(kOutputSize.width, kOutputSize.height), cachedSet.getTextureBounds());
384 
385     // Now check that appending a new cached set properly cleans up RenderEngine resources.
386     CachedSet::Layer& layer3 = *mTestLayers[2]->cachedSetLayer.get();
387     cachedSet.append(CachedSet(layer3));
388 }
389 
TEST_F(CachedSetTest,renderSecureOutput)390 TEST_F(CachedSetTest, renderSecureOutput) {
391     // Skip the 0th layer to ensure that the bounding box of the layers is offset from (0, 0)
392     CachedSet::Layer& layer1 = *mTestLayers[1]->cachedSetLayer.get();
393     sp<mock::LayerFE> layerFE1 = mTestLayers[1]->layerFE;
394     CachedSet::Layer& layer2 = *mTestLayers[2]->cachedSetLayer.get();
395     sp<mock::LayerFE> layerFE2 = mTestLayers[2]->layerFE;
396 
397     CachedSet cachedSet(layer1);
398     cachedSet.append(CachedSet(layer2));
399 
400     std::vector<compositionengine::LayerFE::LayerSettings> clientCompList1;
401     clientCompList1.push_back({});
402     clientCompList1[0].alpha = 0.5f;
403 
404     std::vector<compositionengine::LayerFE::LayerSettings> clientCompList2;
405     clientCompList2.push_back({});
406     clientCompList2[0].alpha = 0.75f;
407 
408     const auto drawLayers =
409             [&](const renderengine::DisplaySettings& displaySettings,
410                 const std::vector<renderengine::LayerSettings>& layers,
411                 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
412                 base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> {
413         EXPECT_EQ(mOutputState.framebufferSpace.getContent(), displaySettings.physicalDisplay);
414         EXPECT_EQ(mOutputState.layerStackSpace.getContent(), displaySettings.clip);
415         EXPECT_EQ(ui::Transform::toRotationFlags(mOutputState.framebufferSpace.getOrientation()),
416                   displaySettings.orientation);
417         EXPECT_EQ(0.5f, layers[0].alpha);
418         EXPECT_EQ(0.75f, layers[1].alpha);
419         EXPECT_EQ(ui::Dataspace::SRGB, displaySettings.outputDataspace);
420 
421         return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
422     };
423 
424     EXPECT_CALL(*layerFE1,
425                 prepareClientCompositionList(ClientCompositionTargetSettingsSecureEq(true)))
426             .WillOnce(Return(clientCompList1));
427     EXPECT_CALL(*layerFE2,
428                 prepareClientCompositionList(ClientCompositionTargetSettingsSecureEq(true)))
429             .WillOnce(Return(clientCompList2));
430     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _, _)).WillOnce(Invoke(drawLayers));
431     mOutputState.isSecure = true;
432     cachedSet.render(mRenderEngine, mTexturePool, mOutputState, true);
433     expectReadyBuffer(cachedSet);
434 
435     EXPECT_EQ(mOutputState.framebufferSpace, cachedSet.getOutputSpace());
436     EXPECT_EQ(Rect(kOutputSize.width, kOutputSize.height), cachedSet.getTextureBounds());
437 
438     // Now check that appending a new cached set properly cleans up RenderEngine resources.
439     CachedSet::Layer& layer3 = *mTestLayers[2]->cachedSetLayer.get();
440     cachedSet.append(CachedSet(layer3));
441 }
442 
TEST_F(CachedSetTest,renderWhitePoint)443 TEST_F(CachedSetTest, renderWhitePoint) {
444     // Skip the 0th layer to ensure that the bounding box of the layers is offset from (0, 0)
445     CachedSet::Layer& layer1 = *mTestLayers[1]->cachedSetLayer.get();
446     sp<mock::LayerFE> layerFE1 = mTestLayers[1]->layerFE;
447     CachedSet::Layer& layer2 = *mTestLayers[2]->cachedSetLayer.get();
448     sp<mock::LayerFE> layerFE2 = mTestLayers[2]->layerFE;
449 
450     CachedSet cachedSet(layer1);
451     cachedSet.append(CachedSet(layer2));
452 
453     std::vector<compositionengine::LayerFE::LayerSettings> clientCompList1;
454     clientCompList1.push_back({});
455 
456     std::vector<compositionengine::LayerFE::LayerSettings> clientCompList2;
457     clientCompList2.push_back({});
458 
459     mOutputState.displayBrightnessNits = 400.f;
460 
461     const auto drawLayers =
462             [&](const renderengine::DisplaySettings& displaySettings,
463                 const std::vector<renderengine::LayerSettings>&,
464                 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
465                 base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> {
466         EXPECT_EQ(mOutputState.displayBrightnessNits, displaySettings.targetLuminanceNits);
467         return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
468     };
469 
470     EXPECT_CALL(*layerFE1,
471                 prepareClientCompositionList(ClientCompositionTargetSettingsWhitePointEq(
472                         mOutputState.displayBrightnessNits)))
473             .WillOnce(Return(clientCompList1));
474     EXPECT_CALL(*layerFE2,
475                 prepareClientCompositionList(ClientCompositionTargetSettingsWhitePointEq(
476                         mOutputState.displayBrightnessNits)))
477             .WillOnce(Return(clientCompList2));
478     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _, _)).WillOnce(Invoke(drawLayers));
479     mOutputState.isSecure = true;
480     cachedSet.render(mRenderEngine, mTexturePool, mOutputState, true);
481     expectReadyBuffer(cachedSet);
482 
483     EXPECT_EQ(mOutputState.framebufferSpace, cachedSet.getOutputSpace());
484     EXPECT_EQ(Rect(kOutputSize.width, kOutputSize.height), cachedSet.getTextureBounds());
485 
486     // Now check that appending a new cached set properly cleans up RenderEngine resources.
487     CachedSet::Layer& layer3 = *mTestLayers[2]->cachedSetLayer.get();
488     cachedSet.append(CachedSet(layer3));
489 }
490 
TEST_F(CachedSetTest,renderWhitePointNoColorTransform)491 TEST_F(CachedSetTest, renderWhitePointNoColorTransform) {
492     // Skip the 0th layer to ensure that the bounding box of the layers is offset from (0, 0)
493     // This is a duplicate of the "renderWhitePoint" test, but setting "deviceHandlesColorTransform"
494     // to false, in the render call.
495 
496     CachedSet::Layer& layer1 = *mTestLayers[1]->cachedSetLayer.get();
497     sp<mock::LayerFE> layerFE1 = mTestLayers[1]->layerFE;
498     CachedSet::Layer& layer2 = *mTestLayers[2]->cachedSetLayer.get();
499     sp<mock::LayerFE> layerFE2 = mTestLayers[2]->layerFE;
500 
501     CachedSet cachedSet(layer1);
502     cachedSet.append(CachedSet(layer2));
503 
504     std::vector<compositionengine::LayerFE::LayerSettings> clientCompList1;
505     clientCompList1.push_back({});
506 
507     std::vector<compositionengine::LayerFE::LayerSettings> clientCompList2;
508     clientCompList2.push_back({});
509 
510     mOutputState.displayBrightnessNits = 400.f;
511 
512     const auto drawLayers =
513             [&](const renderengine::DisplaySettings& displaySettings,
514                 const std::vector<renderengine::LayerSettings>&,
515                 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
516                 base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> {
517         EXPECT_EQ(mOutputState.displayBrightnessNits, displaySettings.targetLuminanceNits);
518         return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
519     };
520 
521     EXPECT_CALL(*layerFE1,
522                 prepareClientCompositionList(ClientCompositionTargetSettingsWhitePointEq(
523                         mOutputState.displayBrightnessNits)))
524             .WillOnce(Return(clientCompList1));
525     EXPECT_CALL(*layerFE2,
526                 prepareClientCompositionList(ClientCompositionTargetSettingsWhitePointEq(
527                         mOutputState.displayBrightnessNits)))
528             .WillOnce(Return(clientCompList2));
529     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _, _)).WillOnce(Invoke(drawLayers));
530     mOutputState.isSecure = true;
531     cachedSet.render(mRenderEngine, mTexturePool, mOutputState, false);
532     expectReadyBuffer(cachedSet);
533 
534     EXPECT_EQ(mOutputState.framebufferSpace, cachedSet.getOutputSpace());
535     EXPECT_EQ(Rect(kOutputSize.width, kOutputSize.height), cachedSet.getTextureBounds());
536 
537     // Now check that appending a new cached set properly cleans up RenderEngine resources.
538     CachedSet::Layer& layer3 = *mTestLayers[2]->cachedSetLayer.get();
539     cachedSet.append(CachedSet(layer3));
540 }
541 
TEST_F(CachedSetTest,rendersWithOffsetFramebufferContent)542 TEST_F(CachedSetTest, rendersWithOffsetFramebufferContent) {
543     // Skip the 0th layer to ensure that the bounding box of the layers is offset from (0, 0)
544     CachedSet::Layer& layer1 = *mTestLayers[1]->cachedSetLayer.get();
545     sp<mock::LayerFE> layerFE1 = mTestLayers[1]->layerFE;
546     CachedSet::Layer& layer2 = *mTestLayers[2]->cachedSetLayer.get();
547     sp<mock::LayerFE> layerFE2 = mTestLayers[2]->layerFE;
548 
549     CachedSet cachedSet(layer1);
550     cachedSet.append(CachedSet(layer2));
551 
552     std::vector<compositionengine::LayerFE::LayerSettings> clientCompList1;
553     clientCompList1.push_back({});
554     clientCompList1[0].alpha = 0.5f;
555 
556     std::vector<compositionengine::LayerFE::LayerSettings> clientCompList2;
557     clientCompList2.push_back({});
558     clientCompList2[0].alpha = 0.75f;
559 
560     mOutputState.framebufferSpace = ProjectionSpace(ui::Size(10, 20), Rect(2, 3, 10, 5));
561 
562     const auto drawLayers =
563             [&](const renderengine::DisplaySettings& displaySettings,
564                 const std::vector<renderengine::LayerSettings>& layers,
565                 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
566                 base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> {
567         EXPECT_EQ(mOutputState.framebufferSpace.getContent(), displaySettings.physicalDisplay);
568         EXPECT_EQ(mOutputState.layerStackSpace.getContent(), displaySettings.clip);
569         EXPECT_EQ(ui::Transform::toRotationFlags(mOutputState.framebufferSpace.getOrientation()),
570                   displaySettings.orientation);
571         EXPECT_EQ(0.5f, layers[0].alpha);
572         EXPECT_EQ(0.75f, layers[1].alpha);
573         EXPECT_EQ(ui::Dataspace::SRGB, displaySettings.outputDataspace);
574 
575         return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
576     };
577 
578     EXPECT_CALL(*layerFE1, prepareClientCompositionList(_)).WillOnce(Return(clientCompList1));
579     EXPECT_CALL(*layerFE2, prepareClientCompositionList(_)).WillOnce(Return(clientCompList2));
580     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _, _)).WillOnce(Invoke(drawLayers));
581     cachedSet.render(mRenderEngine, mTexturePool, mOutputState, true);
582     expectReadyBuffer(cachedSet);
583 
584     EXPECT_EQ(mOutputState.framebufferSpace, cachedSet.getOutputSpace());
585 
586     // Now check that appending a new cached set properly cleans up RenderEngine resources.
587     CachedSet::Layer& layer3 = *mTestLayers[2]->cachedSetLayer.get();
588     cachedSet.append(CachedSet(layer3));
589 }
590 
TEST_F(CachedSetTest,holePunch_requiresBuffer)591 TEST_F(CachedSetTest, holePunch_requiresBuffer) {
592     CachedSet::Layer& layer1 = *mTestLayers[0]->cachedSetLayer.get();
593     auto& layerFECompositionState = mTestLayers[0]->layerFECompositionState;
594     layerFECompositionState.blendMode = hal::BlendMode::NONE;
595     sp<mock::LayerFE> layerFE1 = mTestLayers[0]->layerFE;
596 
597     CachedSet cachedSet(layer1);
598     EXPECT_CALL(*layerFE1, hasRoundedCorners()).WillRepeatedly(Return(true));
599 
600     EXPECT_FALSE(cachedSet.requiresHolePunch());
601 }
602 
TEST_F(CachedSetTest,holePunch_requiresRoundedCorners)603 TEST_F(CachedSetTest, holePunch_requiresRoundedCorners) {
604     CachedSet::Layer& layer1 = *mTestLayers[0]->cachedSetLayer.get();
605     auto& layerFECompositionState = mTestLayers[0]->layerFECompositionState;
606     layerFECompositionState.buffer = sp<GraphicBuffer>::make();
607     layerFECompositionState.blendMode = hal::BlendMode::NONE;
608 
609     CachedSet cachedSet(layer1);
610 
611     EXPECT_FALSE(cachedSet.requiresHolePunch());
612 }
613 
TEST_F(CachedSetTest,holePunch_requiresSingleLayer)614 TEST_F(CachedSetTest, holePunch_requiresSingleLayer) {
615     CachedSet::Layer& layer1 = *mTestLayers[0]->cachedSetLayer.get();
616     auto& layerFECompositionState = mTestLayers[0]->layerFECompositionState;
617     layerFECompositionState.buffer = sp<GraphicBuffer>::make();
618     layerFECompositionState.blendMode = hal::BlendMode::NONE;
619     sp<mock::LayerFE> layerFE = mTestLayers[0]->layerFE;
620     EXPECT_CALL(*layerFE, hasRoundedCorners()).WillRepeatedly(Return(true));
621 
622     CachedSet::Layer& layer2 = *mTestLayers[1]->cachedSetLayer.get();
623 
624     CachedSet cachedSet(layer1);
625     cachedSet.append(layer2);
626 
627     EXPECT_FALSE(cachedSet.requiresHolePunch());
628 }
629 
TEST_F(CachedSetTest,holePunch_requiresNonHdr)630 TEST_F(CachedSetTest, holePunch_requiresNonHdr) {
631     mTestLayers[0]->outputLayerCompositionState.dataspace = ui::Dataspace::BT2020_PQ;
632     mTestLayers[0]->layerState->update(&mTestLayers[0]->outputLayer);
633 
634     CachedSet::Layer& layer = *mTestLayers[0]->cachedSetLayer.get();
635     auto& layerFECompositionState = mTestLayers[0]->layerFECompositionState;
636     layerFECompositionState.buffer = sp<GraphicBuffer>::make();
637     layerFECompositionState.blendMode = hal::BlendMode::NONE;
638     sp<mock::LayerFE> layerFE = mTestLayers[0]->layerFE;
639 
640     CachedSet cachedSet(layer);
641     EXPECT_CALL(*layerFE, hasRoundedCorners()).WillRepeatedly(Return(true));
642 
643     EXPECT_FALSE(cachedSet.requiresHolePunch());
644 }
645 
TEST_F(CachedSetTest,holePunch_requiresNonBT601_625)646 TEST_F(CachedSetTest, holePunch_requiresNonBT601_625) {
647     mTestLayers[0]->outputLayerCompositionState.dataspace = ui::Dataspace::STANDARD_BT601_625;
648     mTestLayers[0]->layerState->update(&mTestLayers[0]->outputLayer);
649 
650     CachedSet::Layer& layer = *mTestLayers[0]->cachedSetLayer.get();
651     auto& layerFECompositionState = mTestLayers[0]->layerFECompositionState;
652     layerFECompositionState.buffer = sp<GraphicBuffer>::make();
653     layerFECompositionState.blendMode = hal::BlendMode::NONE;
654     sp<mock::LayerFE> layerFE = mTestLayers[0]->layerFE;
655 
656     CachedSet cachedSet(layer);
657     EXPECT_CALL(*layerFE, hasRoundedCorners()).WillRepeatedly(Return(true));
658 
659     EXPECT_FALSE(cachedSet.requiresHolePunch());
660 }
661 
TEST_F(CachedSetTest,holePunch_requiresNoBlending)662 TEST_F(CachedSetTest, holePunch_requiresNoBlending) {
663     CachedSet::Layer& layer = *mTestLayers[0]->cachedSetLayer.get();
664     auto& layerFECompositionState = mTestLayers[0]->layerFECompositionState;
665     layerFECompositionState.buffer = sp<GraphicBuffer>::make();
666     layerFECompositionState.blendMode = hal::BlendMode::PREMULTIPLIED;
667     sp<mock::LayerFE> layerFE = mTestLayers[0]->layerFE;
668 
669     CachedSet cachedSet(layer);
670     EXPECT_CALL(*layerFE, hasRoundedCorners()).WillRepeatedly(Return(true));
671 
672     EXPECT_FALSE(cachedSet.requiresHolePunch());
673 }
674 
TEST_F(CachedSetTest,requiresHolePunch)675 TEST_F(CachedSetTest, requiresHolePunch) {
676     CachedSet::Layer& layer = *mTestLayers[0]->cachedSetLayer.get();
677     auto& layerFECompositionState = mTestLayers[0]->layerFECompositionState;
678     layerFECompositionState.buffer = sp<GraphicBuffer>::make();
679     layerFECompositionState.blendMode = hal::BlendMode::NONE;
680     sp<mock::LayerFE> layerFE = mTestLayers[0]->layerFE;
681 
682     CachedSet cachedSet(layer);
683     EXPECT_CALL(*layerFE, hasRoundedCorners()).WillRepeatedly(Return(true));
684 
685     EXPECT_TRUE(cachedSet.requiresHolePunch());
686 }
687 
TEST_F(CachedSetTest,holePunch_requiresDeviceComposition)688 TEST_F(CachedSetTest, holePunch_requiresDeviceComposition) {
689     CachedSet::Layer& layer = *mTestLayers[0]->cachedSetLayer.get();
690     sp<mock::LayerFE> layerFE = mTestLayers[0]->layerFE;
691     auto& layerFECompositionState = mTestLayers[0]->layerFECompositionState;
692     layerFECompositionState.buffer = sp<GraphicBuffer>::make();
693     layerFECompositionState.blendMode = hal::BlendMode::NONE;
694     layerFECompositionState.forceClientComposition = true;
695 
696     CachedSet cachedSet(layer);
697     EXPECT_CALL(*layerFE, hasRoundedCorners()).WillRepeatedly(Return(true));
698 
699     EXPECT_FALSE(cachedSet.requiresHolePunch());
700 }
701 
TEST_F(CachedSetTest,addHolePunch_requiresOverlap)702 TEST_F(CachedSetTest, addHolePunch_requiresOverlap) {
703     CachedSet::Layer& layer1 = *mTestLayers[0]->cachedSetLayer.get();
704     CachedSet::Layer& layer2 = *mTestLayers[1]->cachedSetLayer.get();
705     CachedSet::Layer& layer3 = *mTestLayers[2]->cachedSetLayer.get();
706 
707     CachedSet cachedSet(layer1);
708     cachedSet.addLayer(layer2.getState(), kStartTime + 10ms);
709 
710     cachedSet.addHolePunchLayerIfFeasible(layer3, true);
711 
712     ASSERT_EQ(nullptr, cachedSet.getHolePunchLayer());
713 }
714 
TEST_F(CachedSetTest,addHolePunch_requiresOpaque)715 TEST_F(CachedSetTest, addHolePunch_requiresOpaque) {
716     mTestLayers[0]->outputLayerCompositionState.displayFrame = Rect(0, 0, 5, 5);
717     mTestLayers[0]->layerFECompositionState.isOpaque = false;
718     CachedSet::Layer& layer1 = *mTestLayers[0]->cachedSetLayer.get();
719     CachedSet::Layer& layer2 = *mTestLayers[1]->cachedSetLayer.get();
720     CachedSet::Layer& layer3 = *mTestLayers[2]->cachedSetLayer.get();
721 
722     CachedSet cachedSet(layer1);
723     cachedSet.addLayer(layer2.getState(), kStartTime + 10ms);
724 
725     cachedSet.addHolePunchLayerIfFeasible(layer3, false);
726 
727     ASSERT_EQ(nullptr, cachedSet.getHolePunchLayer());
728 }
729 
TEST_F(CachedSetTest,addHolePunch_opaque)730 TEST_F(CachedSetTest, addHolePunch_opaque) {
731     mTestLayers[0]->outputLayerCompositionState.displayFrame = Rect(0, 0, 5, 5);
732     mTestLayers[0]->layerFECompositionState.isOpaque = true;
733     CachedSet::Layer& layer1 = *mTestLayers[0]->cachedSetLayer.get();
734     CachedSet::Layer& layer2 = *mTestLayers[1]->cachedSetLayer.get();
735     CachedSet::Layer& layer3 = *mTestLayers[2]->cachedSetLayer.get();
736 
737     CachedSet cachedSet(layer1);
738     cachedSet.addLayer(layer2.getState(), kStartTime + 10ms);
739 
740     cachedSet.addHolePunchLayerIfFeasible(layer3, false);
741 
742     ASSERT_EQ(&mTestLayers[2]->outputLayer, cachedSet.getHolePunchLayer());
743 }
744 
TEST_F(CachedSetTest,addHolePunch_firstLayer)745 TEST_F(CachedSetTest, addHolePunch_firstLayer) {
746     mTestLayers[0]->outputLayerCompositionState.displayFrame = Rect(0, 0, 5, 5);
747     mTestLayers[0]->layerFECompositionState.isOpaque = false;
748     CachedSet::Layer& layer1 = *mTestLayers[0]->cachedSetLayer.get();
749     CachedSet::Layer& layer2 = *mTestLayers[1]->cachedSetLayer.get();
750     CachedSet::Layer& layer3 = *mTestLayers[2]->cachedSetLayer.get();
751 
752     CachedSet cachedSet(layer1);
753     cachedSet.addLayer(layer2.getState(), kStartTime + 10ms);
754 
755     cachedSet.addHolePunchLayerIfFeasible(layer3, true);
756 
757     ASSERT_EQ(&mTestLayers[2]->outputLayer, cachedSet.getHolePunchLayer());
758 }
759 
TEST_F(CachedSetTest,addHolePunch)760 TEST_F(CachedSetTest, addHolePunch) {
761     mTestLayers[0]->outputLayerCompositionState.displayFrame = Rect(0, 0, 5, 5);
762     CachedSet::Layer& layer1 = *mTestLayers[0]->cachedSetLayer.get();
763     sp<mock::LayerFE> layerFE1 = mTestLayers[0]->layerFE;
764 
765     CachedSet::Layer& layer2 = *mTestLayers[1]->cachedSetLayer.get();
766     sp<mock::LayerFE> layerFE2 = mTestLayers[1]->layerFE;
767 
768     CachedSet::Layer& layer3 = *mTestLayers[2]->cachedSetLayer.get();
769     sp<mock::LayerFE> layerFE3 = mTestLayers[2]->layerFE;
770 
771     CachedSet cachedSet(layer1);
772     cachedSet.addLayer(layer2.getState(), kStartTime + 10ms);
773 
774     cachedSet.addHolePunchLayerIfFeasible(layer3, true);
775 
776     std::vector<compositionengine::LayerFE::LayerSettings> clientCompList1;
777     clientCompList1.push_back({});
778     std::vector<compositionengine::LayerFE::LayerSettings> clientCompList2;
779     clientCompList2.push_back({});
780     std::vector<compositionengine::LayerFE::LayerSettings> clientCompList3;
781     clientCompList3.push_back({});
782 
783     clientCompList3[0].source.buffer.buffer =
784             std::make_shared<renderengine::mock::FakeExternalTexture>(1U /*width*/, 1U /*height*/,
785                                                                       1ULL /* bufferId */,
786                                                                       HAL_PIXEL_FORMAT_RGBA_8888,
787                                                                       0ULL /*usage*/);
788 
789     EXPECT_CALL(*layerFE1, prepareClientCompositionList(_)).WillOnce(Return(clientCompList1));
790     EXPECT_CALL(*layerFE2, prepareClientCompositionList(_)).WillOnce(Return(clientCompList2));
791     EXPECT_CALL(*layerFE3, prepareClientCompositionList(_)).WillOnce(Return(clientCompList3));
792 
793     const auto drawLayers =
794             [&](const renderengine::DisplaySettings&,
795                 const std::vector<renderengine::LayerSettings>& layers,
796                 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
797                 base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> {
798         // If the highlight layer is enabled, it will increase the size by 1.
799         // We're interested in the third layer either way.
800         EXPECT_GE(layers.size(), 4u);
801         {
802             const auto holePunchSettings = layers[3];
803             EXPECT_EQ(nullptr, holePunchSettings.source.buffer.buffer);
804             EXPECT_EQ(half3(0.0f, 0.0f, 0.0f), holePunchSettings.source.solidColor);
805             EXPECT_TRUE(holePunchSettings.disableBlending);
806             EXPECT_EQ(0.0f, holePunchSettings.alpha);
807         }
808 
809         {
810             const auto holePunchBackgroundSettings = layers[0];
811             EXPECT_EQ(nullptr, holePunchBackgroundSettings.source.buffer.buffer);
812             EXPECT_EQ(half3(0.0f, 0.0f, 0.0f), holePunchBackgroundSettings.source.solidColor);
813             EXPECT_FALSE(holePunchBackgroundSettings.disableBlending);
814             EXPECT_EQ(1.0f, holePunchBackgroundSettings.alpha);
815         }
816 
817         return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
818     };
819 
820     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _, _)).WillOnce(Invoke(drawLayers));
821     cachedSet.render(mRenderEngine, mTexturePool, mOutputState, true);
822 }
823 
TEST_F(CachedSetTest,addHolePunch_noBuffer)824 TEST_F(CachedSetTest, addHolePunch_noBuffer) {
825     // Same as addHolePunch, except that clientCompList3 does not contain a
826     // buffer. This imitates the case where the buffer had protected content, so
827     // BufferLayer did not add it to the LayerSettings. This should not assert.
828     mTestLayers[0]->outputLayerCompositionState.displayFrame = Rect(0, 0, 5, 5);
829     CachedSet::Layer& layer1 = *mTestLayers[0]->cachedSetLayer.get();
830     sp<mock::LayerFE> layerFE1 = mTestLayers[0]->layerFE;
831 
832     CachedSet::Layer& layer2 = *mTestLayers[1]->cachedSetLayer.get();
833     sp<mock::LayerFE> layerFE2 = mTestLayers[1]->layerFE;
834 
835     CachedSet::Layer& layer3 = *mTestLayers[2]->cachedSetLayer.get();
836     sp<mock::LayerFE> layerFE3 = mTestLayers[2]->layerFE;
837 
838     CachedSet cachedSet(layer1);
839     cachedSet.addLayer(layer2.getState(), kStartTime + 10ms);
840 
841     cachedSet.addHolePunchLayerIfFeasible(layer3, true);
842 
843     std::vector<compositionengine::LayerFE::LayerSettings> clientCompList1;
844     clientCompList1.push_back({});
845     std::vector<compositionengine::LayerFE::LayerSettings> clientCompList2;
846     clientCompList2.push_back({});
847     std::vector<compositionengine::LayerFE::LayerSettings> clientCompList3;
848     clientCompList3.push_back({});
849 
850     EXPECT_CALL(*layerFE1, prepareClientCompositionList(_)).WillOnce(Return(clientCompList1));
851     EXPECT_CALL(*layerFE2, prepareClientCompositionList(_)).WillOnce(Return(clientCompList2));
852     EXPECT_CALL(*layerFE3, prepareClientCompositionList(_)).WillOnce(Return(clientCompList3));
853 
854     const auto drawLayers =
855             [&](const renderengine::DisplaySettings&,
856                 const std::vector<renderengine::LayerSettings>& layers,
857                 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
858                 base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> {
859         // If the highlight layer is enabled, it will increase the size by 1.
860         // We're interested in the third layer either way.
861         EXPECT_GE(layers.size(), 4u);
862 
863         {
864             const auto holePunchSettings = layers[3];
865             EXPECT_EQ(nullptr, holePunchSettings.source.buffer.buffer);
866             EXPECT_EQ(half3(0.0f, 0.0f, 0.0f), holePunchSettings.source.solidColor);
867             EXPECT_TRUE(holePunchSettings.disableBlending);
868             EXPECT_EQ(0.0f, holePunchSettings.alpha);
869         }
870 
871         {
872             const auto holePunchBackgroundSettings = layers[0];
873             EXPECT_EQ(nullptr, holePunchBackgroundSettings.source.buffer.buffer);
874             EXPECT_EQ(half3(0.0f, 0.0f, 0.0f), holePunchBackgroundSettings.source.solidColor);
875             EXPECT_FALSE(holePunchBackgroundSettings.disableBlending);
876             EXPECT_EQ(1.0f, holePunchBackgroundSettings.alpha);
877         }
878 
879         return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
880     };
881 
882     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _, _)).WillOnce(Invoke(drawLayers));
883     cachedSet.render(mRenderEngine, mTexturePool, mOutputState, true);
884 }
885 
TEST_F(CachedSetTest,append_removesHolePunch)886 TEST_F(CachedSetTest, append_removesHolePunch) {
887     mTestLayers[0]->outputLayerCompositionState.displayFrame = Rect(0, 0, 5, 5);
888     mTestLayers[0]->layerFECompositionState.isOpaque = true;
889     CachedSet::Layer& layer1 = *mTestLayers[0]->cachedSetLayer.get();
890     CachedSet::Layer& layer2 = *mTestLayers[1]->cachedSetLayer.get();
891     CachedSet::Layer& layer3 = *mTestLayers[2]->cachedSetLayer.get();
892 
893     CachedSet cachedSet(layer1);
894     cachedSet.addLayer(layer2.getState(), kStartTime + 10ms);
895 
896     cachedSet.addHolePunchLayerIfFeasible(layer3, false);
897 
898     ASSERT_EQ(&mTestLayers[2]->outputLayer, cachedSet.getHolePunchLayer());
899 
900     CachedSet cachedSet3(layer3);
901     cachedSet.append(cachedSet3);
902     ASSERT_EQ(nullptr, cachedSet.getHolePunchLayer());
903 }
904 
TEST_F(CachedSetTest,decompose_removesHolePunch)905 TEST_F(CachedSetTest, decompose_removesHolePunch) {
906     mTestLayers[0]->outputLayerCompositionState.displayFrame = Rect(0, 0, 5, 5);
907     CachedSet::Layer& layer1 = *mTestLayers[0]->cachedSetLayer.get();
908     CachedSet::Layer& layer2 = *mTestLayers[1]->cachedSetLayer.get();
909     CachedSet::Layer& layer3 = *mTestLayers[2]->cachedSetLayer.get();
910 
911     CachedSet cachedSet(layer1);
912     cachedSet.addLayer(layer2.getState(), kStartTime + 10ms);
913 
914     cachedSet.addHolePunchLayerIfFeasible(layer3, true);
915 
916     ASSERT_EQ(&mTestLayers[2]->outputLayer, cachedSet.getHolePunchLayer());
917 
918     std::vector<CachedSet> decomposed = cachedSet.decompose();
919     EXPECT_EQ(2u, decomposed.size());
920     for (const auto& set : decomposed) {
921         EXPECT_EQ(nullptr, set.getHolePunchLayer());
922     }
923 }
924 
TEST_F(CachedSetTest,hasBlurBehind)925 TEST_F(CachedSetTest, hasBlurBehind) {
926     mTestLayers[1]->layerFECompositionState.backgroundBlurRadius = 1;
927     mTestLayers[1]->layerState->update(&mTestLayers[1]->outputLayer);
928     mTestLayers[2]->layerFECompositionState.blurRegions.push_back(
929             BlurRegion{1, 0, 0, 0, 0, 0, 0, 0, 0, 0});
930     mTestLayers[2]->layerState->update(&mTestLayers[2]->outputLayer);
931 
932     CachedSet::Layer& layer1 = *mTestLayers[0]->cachedSetLayer.get();
933     CachedSet::Layer& layer2 = *mTestLayers[1]->cachedSetLayer.get();
934     CachedSet::Layer& layer3 = *mTestLayers[2]->cachedSetLayer.get();
935 
936     CachedSet cachedSet1(layer1);
937     CachedSet cachedSet2(layer2);
938     CachedSet cachedSet3(layer3);
939 
940     // Cached set 4 will consist of layers 1 and 2, which will contain a blur behind
941     CachedSet cachedSet4(layer1);
942     cachedSet4.addLayer(layer2.getState(), kStartTime);
943 
944     EXPECT_FALSE(cachedSet1.hasBlurBehind());
945     EXPECT_TRUE(cachedSet2.hasBlurBehind());
946     EXPECT_TRUE(cachedSet3.hasBlurBehind());
947     EXPECT_TRUE(cachedSet4.hasBlurBehind());
948 }
949 
TEST_F(CachedSetTest,addBackgroundBlurLayer)950 TEST_F(CachedSetTest, addBackgroundBlurLayer) {
951     CachedSet::Layer& layer1 = *mTestLayers[0]->cachedSetLayer.get();
952     CachedSet::Layer& layer2 = *mTestLayers[1]->cachedSetLayer.get();
953     CachedSet cachedSet(layer1);
954 
955     EXPECT_EQ(nullptr, cachedSet.getBlurLayer());
956 
957     cachedSet.addBackgroundBlurLayer(layer2);
958     EXPECT_EQ(layer2.getState()->getOutputLayer(), cachedSet.getBlurLayer());
959 }
960 
TEST_F(CachedSetTest,addBlur)961 TEST_F(CachedSetTest, addBlur) {
962     mTestLayers[0]->outputLayerCompositionState.displayFrame = Rect(0, 0, 5, 5);
963     CachedSet::Layer& layer1 = *mTestLayers[0]->cachedSetLayer.get();
964     sp<mock::LayerFE> layerFE1 = mTestLayers[0]->layerFE;
965 
966     CachedSet::Layer& layer2 = *mTestLayers[1]->cachedSetLayer.get();
967     sp<mock::LayerFE> layerFE2 = mTestLayers[1]->layerFE;
968 
969     CachedSet::Layer& layer3 = *mTestLayers[2]->cachedSetLayer.get();
970     sp<mock::LayerFE> layerFE3 = mTestLayers[2]->layerFE;
971 
972     CachedSet cachedSet(layer1);
973     cachedSet.addLayer(layer2.getState(), kStartTime + 10ms);
974 
975     cachedSet.addBackgroundBlurLayer(layer3);
976 
977     std::vector<compositionengine::LayerFE::LayerSettings> clientCompList1;
978     clientCompList1.push_back({});
979     std::vector<compositionengine::LayerFE::LayerSettings> clientCompList2;
980     clientCompList2.push_back({});
981     std::vector<compositionengine::LayerFE::LayerSettings> clientCompList3;
982     clientCompList3.push_back({});
983 
984     clientCompList3[0].source.buffer.buffer =
985             std::make_shared<renderengine::mock::FakeExternalTexture>(1U /*width*/, 1U /*height*/,
986                                                                       1ULL /* bufferId */,
987                                                                       HAL_PIXEL_FORMAT_RGBA_8888,
988                                                                       0ULL /*usage*/);
989 
990     EXPECT_CALL(*layerFE1,
991                 prepareClientCompositionList(ClientCompositionTargetSettingsBlurSettingsEq(
992                         compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::
993                                 Enabled)))
994             .WillOnce(Return(clientCompList1));
995     EXPECT_CALL(*layerFE2,
996                 prepareClientCompositionList(ClientCompositionTargetSettingsBlurSettingsEq(
997                         compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::
998                                 Enabled)))
999             .WillOnce(Return(clientCompList2));
1000     EXPECT_CALL(*layerFE3,
1001                 prepareClientCompositionList(ClientCompositionTargetSettingsBlurSettingsEq(
1002                         compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::
1003                                 BackgroundBlurOnly)))
1004             .WillOnce(Return(clientCompList3));
1005 
1006     const auto drawLayers =
1007             [&](const renderengine::DisplaySettings&,
1008                 const std::vector<renderengine::LayerSettings>& layers,
1009                 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
1010                 base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> {
1011         // If the highlight layer is enabled, it will increase the size by 1.
1012         // We're interested in the third layer either way.
1013         EXPECT_GE(layers.size(), 3u);
1014         const auto blurSettings = layers[2];
1015         EXPECT_TRUE(blurSettings.skipContentDraw);
1016         EXPECT_EQ(half3(0.0f, 0.0f, 0.0f), blurSettings.source.solidColor);
1017         EXPECT_EQ(0.0f, blurSettings.alpha);
1018 
1019         return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
1020     };
1021 
1022     EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _, _)).WillOnce(Invoke(drawLayers));
1023     cachedSet.render(mRenderEngine, mTexturePool, mOutputState, true);
1024 }
1025 
1026 } // namespace
1027 } // namespace android::compositionengine
1028