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