1 /*
2  * Copyright 2018 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 <com_android_graphics_surfaceflinger_flags.h>
18 #include <common/test/FlagUtils.h>
19 #include <compositionengine/CompositionRefreshArgs.h>
20 #include <compositionengine/LayerFECompositionState.h>
21 #include <compositionengine/impl/CompositionEngine.h>
22 #include <compositionengine/mock/LayerFE.h>
23 #include <compositionengine/mock/Output.h>
24 #include <compositionengine/mock/OutputLayer.h>
25 #include <ftl/future.h>
26 #include <gtest/gtest.h>
27 #include <renderengine/mock/RenderEngine.h>
28 
29 #include "MockHWComposer.h"
30 #include "TimeStats/TimeStats.h"
31 #include "gmock/gmock.h"
32 
33 #include <variant>
34 
35 using namespace com::android::graphics::surfaceflinger;
36 
37 namespace android::compositionengine {
38 namespace {
39 
40 using ::testing::_;
41 using ::testing::DoAll;
42 using ::testing::InSequence;
43 using ::testing::Ref;
44 using ::testing::Return;
45 using ::testing::ReturnRef;
46 using ::testing::SaveArg;
47 using ::testing::StrictMock;
48 
49 struct CompositionEngineTest : public testing::Test {
50     std::shared_ptr<TimeStats> mTimeStats;
51 
52     impl::CompositionEngine mEngine;
53     CompositionRefreshArgs mRefreshArgs;
54 
55     std::shared_ptr<mock::Output> mOutput1{std::make_shared<StrictMock<mock::Output>>()};
56     std::shared_ptr<mock::Output> mOutput2{std::make_shared<StrictMock<mock::Output>>()};
57     std::shared_ptr<mock::Output> mOutput3{std::make_shared<StrictMock<mock::Output>>()};
58 };
59 
TEST_F(CompositionEngineTest,canInstantiateCompositionEngine)60 TEST_F(CompositionEngineTest, canInstantiateCompositionEngine) {
61     auto engine = impl::createCompositionEngine();
62     EXPECT_TRUE(engine.get() != nullptr);
63 }
64 
TEST_F(CompositionEngineTest,canSetHWComposer)65 TEST_F(CompositionEngineTest, canSetHWComposer) {
66     android::mock::HWComposer* hwc = new StrictMock<android::mock::HWComposer>();
67     mEngine.setHwComposer(std::unique_ptr<android::HWComposer>(hwc));
68 
69     EXPECT_EQ(hwc, &mEngine.getHwComposer());
70 }
71 
TEST_F(CompositionEngineTest,canSetRenderEngine)72 TEST_F(CompositionEngineTest, canSetRenderEngine) {
73     auto renderEngine = std::make_unique<StrictMock<renderengine::mock::RenderEngine>>();
74     mEngine.setRenderEngine(renderEngine.get());
75 
76     EXPECT_EQ(renderEngine.get(), &mEngine.getRenderEngine());
77 }
78 
TEST_F(CompositionEngineTest,canSetTimeStats)79 TEST_F(CompositionEngineTest, canSetTimeStats) {
80     mEngine.setTimeStats(mTimeStats);
81 
82     EXPECT_EQ(mTimeStats.get(), mEngine.getTimeStats());
83 }
84 
85 /*
86  * CompositionEngine::present
87  */
88 
89 struct CompositionEnginePresentTest : public CompositionEngineTest {
90     struct CompositionEnginePartialMock : public impl::CompositionEngine {
91         // These are the overridable functions CompositionEngine::present() may
92         // call, and have separate test coverage.
93         MOCK_METHOD1(preComposition, void(CompositionRefreshArgs&));
94         MOCK_METHOD1(postComposition, void(CompositionRefreshArgs&));
95     };
96 
97     StrictMock<CompositionEnginePartialMock> mEngine;
98 };
99 
TEST_F(CompositionEnginePresentTest,worksWithEmptyRequest)100 TEST_F(CompositionEnginePresentTest, worksWithEmptyRequest) {
101     // present() always calls preComposition() and postComposition()
102     EXPECT_CALL(mEngine, preComposition(Ref(mRefreshArgs)));
103     EXPECT_CALL(mEngine, postComposition(Ref(mRefreshArgs)));
104 
105     mEngine.present(mRefreshArgs);
106 }
107 
TEST_F(CompositionEnginePresentTest,worksAsExpected)108 TEST_F(CompositionEnginePresentTest, worksAsExpected) {
109     // Expect calls to in a certain sequence
110     InSequence seq;
111 
112     // present() always calls preComposition()
113     EXPECT_CALL(mEngine, preComposition(Ref(mRefreshArgs)));
114 
115     // The first step in presenting is to make sure all outputs are prepared.
116     EXPECT_CALL(*mOutput1, prepare(Ref(mRefreshArgs), _));
117     EXPECT_CALL(*mOutput2, prepare(Ref(mRefreshArgs), _));
118     EXPECT_CALL(*mOutput3, prepare(Ref(mRefreshArgs), _));
119 
120     // All of mOutput<i> are StrictMocks. If the flag is true, it will introduce
121     // calls to getDisplayId, which are not relevant to this test.
122     SET_FLAG_FOR_TEST(flags::multithreaded_present, false);
123 
124     // The last step is to actually present each output.
125     EXPECT_CALL(*mOutput1, present(Ref(mRefreshArgs)))
126             .WillOnce(Return(ftl::yield<std::monostate>({})));
127     EXPECT_CALL(*mOutput2, present(Ref(mRefreshArgs)))
128             .WillOnce(Return(ftl::yield<std::monostate>({})));
129     EXPECT_CALL(*mOutput3, present(Ref(mRefreshArgs)))
130             .WillOnce(Return(ftl::yield<std::monostate>({})));
131 
132     // present() always calls postComposition()
133     EXPECT_CALL(mEngine, postComposition(Ref(mRefreshArgs)));
134 
135     mRefreshArgs.outputs = {mOutput1, mOutput2, mOutput3};
136     mEngine.present(mRefreshArgs);
137 }
138 
139 /*
140  * CompositionEngine::updateCursorAsync
141  */
142 
143 struct CompositionEngineUpdateCursorAsyncTest : public CompositionEngineTest {
144 public:
145     struct Layer {
Layerandroid::compositionengine::__anon2b52074d0111::CompositionEngineUpdateCursorAsyncTest::Layer146         Layer() { EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE)); }
147 
148         StrictMock<mock::OutputLayer> outputLayer;
149         sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
150         LayerFECompositionState layerFEState;
151     };
152 
CompositionEngineUpdateCursorAsyncTestandroid::compositionengine::__anon2b52074d0111::CompositionEngineUpdateCursorAsyncTest153     CompositionEngineUpdateCursorAsyncTest() {
154         EXPECT_CALL(*mOutput1, getOutputLayerCount()).WillRepeatedly(Return(0u));
155         EXPECT_CALL(*mOutput1, getOutputLayerOrderedByZByIndex(_)).Times(0);
156 
157         EXPECT_CALL(*mOutput2, getOutputLayerCount()).WillRepeatedly(Return(1u));
158         EXPECT_CALL(*mOutput2, getOutputLayerOrderedByZByIndex(0))
159                 .WillRepeatedly(Return(&mOutput2Layer1.outputLayer));
160 
161         EXPECT_CALL(*mOutput3, getOutputLayerCount()).WillRepeatedly(Return(2u));
162         EXPECT_CALL(*mOutput3, getOutputLayerOrderedByZByIndex(0))
163                 .WillRepeatedly(Return(&mOutput3Layer1.outputLayer));
164         EXPECT_CALL(*mOutput3, getOutputLayerOrderedByZByIndex(1))
165                 .WillRepeatedly(Return(&mOutput3Layer2.outputLayer));
166     }
167 
168     Layer mOutput2Layer1;
169     Layer mOutput3Layer1;
170     Layer mOutput3Layer2;
171 };
172 
TEST_F(CompositionEngineUpdateCursorAsyncTest,handlesNoOutputs)173 TEST_F(CompositionEngineUpdateCursorAsyncTest, handlesNoOutputs) {
174     mEngine.updateCursorAsync(mRefreshArgs);
175 }
176 
TEST_F(CompositionEngineUpdateCursorAsyncTest,handlesNoLayersBeingCursorLayers)177 TEST_F(CompositionEngineUpdateCursorAsyncTest, handlesNoLayersBeingCursorLayers) {
178     EXPECT_CALL(mOutput3Layer1.outputLayer, isHardwareCursor()).WillRepeatedly(Return(false));
179     EXPECT_CALL(mOutput3Layer2.outputLayer, isHardwareCursor()).WillRepeatedly(Return(false));
180     EXPECT_CALL(mOutput2Layer1.outputLayer, isHardwareCursor()).WillRepeatedly(Return(false));
181 
182     mRefreshArgs.outputs = {mOutput1, mOutput2, mOutput3};
183 
184     mEngine.updateCursorAsync(mRefreshArgs);
185 }
186 
TEST_F(CompositionEngineUpdateCursorAsyncTest,handlesMultipleLayersBeingCursorLayers)187 TEST_F(CompositionEngineUpdateCursorAsyncTest, handlesMultipleLayersBeingCursorLayers) {
188     {
189         InSequence seq;
190         EXPECT_CALL(mOutput2Layer1.outputLayer, isHardwareCursor()).WillRepeatedly(Return(true));
191         EXPECT_CALL(mOutput2Layer1.outputLayer, writeCursorPositionToHWC());
192     }
193 
194     {
195         InSequence seq;
196         EXPECT_CALL(mOutput3Layer1.outputLayer, isHardwareCursor()).WillRepeatedly(Return(true));
197         EXPECT_CALL(mOutput3Layer1.outputLayer, writeCursorPositionToHWC());
198     }
199 
200     {
201         InSequence seq;
202         EXPECT_CALL(mOutput3Layer2.outputLayer, isHardwareCursor()).WillRepeatedly(Return(true));
203         EXPECT_CALL(mOutput3Layer2.outputLayer, writeCursorPositionToHWC());
204     }
205 
206     mRefreshArgs.outputs = {mOutput1, mOutput2, mOutput3};
207 
208     mEngine.updateCursorAsync(mRefreshArgs);
209 }
210 
211 /*
212  * CompositionEngine::preComposition
213  */
214 
215 struct CompositionTestPreComposition : public CompositionEngineTest {
216     sp<StrictMock<mock::LayerFE>> mLayer1FE = sp<StrictMock<mock::LayerFE>>::make();
217     sp<StrictMock<mock::LayerFE>> mLayer2FE = sp<StrictMock<mock::LayerFE>>::make();
218     sp<StrictMock<mock::LayerFE>> mLayer3FE = sp<StrictMock<mock::LayerFE>>::make();
219 };
220 
TEST_F(CompositionTestPreComposition,preCompositionSetsFrameTimestamp)221 TEST_F(CompositionTestPreComposition, preCompositionSetsFrameTimestamp) {
222     const nsecs_t before = systemTime(SYSTEM_TIME_MONOTONIC);
223     mRefreshArgs.refreshStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
224     mEngine.preComposition(mRefreshArgs);
225     const nsecs_t after = systemTime(SYSTEM_TIME_MONOTONIC);
226 
227     // The frame timestamp should be between the before and after timestamps
228     EXPECT_GE(mEngine.getLastFrameRefreshTimestamp(), before);
229     EXPECT_LE(mEngine.getLastFrameRefreshTimestamp(), after);
230 }
231 
TEST_F(CompositionTestPreComposition,preCompositionInvokesLayerPreCompositionWithFrameTimestamp)232 TEST_F(CompositionTestPreComposition, preCompositionInvokesLayerPreCompositionWithFrameTimestamp) {
233     nsecs_t ts1 = 0;
234     nsecs_t ts2 = 0;
235     nsecs_t ts3 = 0;
236     EXPECT_CALL(*mLayer1FE, onPreComposition(_)).WillOnce(DoAll(SaveArg<0>(&ts1), Return(false)));
237     EXPECT_CALL(*mLayer2FE, onPreComposition(_)).WillOnce(DoAll(SaveArg<0>(&ts2), Return(false)));
238     EXPECT_CALL(*mLayer3FE, onPreComposition(_)).WillOnce(DoAll(SaveArg<0>(&ts3), Return(false)));
239 
240     mRefreshArgs.outputs = {mOutput1};
241     mRefreshArgs.layers = {mLayer1FE, mLayer2FE, mLayer3FE};
242 
243     mEngine.preComposition(mRefreshArgs);
244 
245     // Each of the onPreComposition calls should used the same refresh timestamp
246     EXPECT_EQ(ts1, mEngine.getLastFrameRefreshTimestamp());
247     EXPECT_EQ(ts2, mEngine.getLastFrameRefreshTimestamp());
248     EXPECT_EQ(ts3, mEngine.getLastFrameRefreshTimestamp());
249 }
250 
TEST_F(CompositionTestPreComposition,preCompositionDefaultsToNoUpdateNeeded)251 TEST_F(CompositionTestPreComposition, preCompositionDefaultsToNoUpdateNeeded) {
252     EXPECT_CALL(*mLayer1FE, onPreComposition(_)).WillOnce(Return(false));
253     EXPECT_CALL(*mLayer2FE, onPreComposition(_)).WillOnce(Return(false));
254     EXPECT_CALL(*mLayer3FE, onPreComposition(_)).WillOnce(Return(false));
255 
256     mEngine.setNeedsAnotherUpdateForTest(true);
257 
258     mRefreshArgs.outputs = {mOutput1};
259     mRefreshArgs.layers = {mLayer1FE, mLayer2FE, mLayer3FE};
260 
261     mEngine.preComposition(mRefreshArgs);
262 
263     // The call should have cleared the needsAnotherUpdate flag
264     EXPECT_FALSE(mEngine.needsAnotherUpdate());
265 }
266 
TEST_F(CompositionTestPreComposition,preCompositionSetsNeedsAnotherUpdateIfAtLeastOneLayerRequestsIt)267 TEST_F(CompositionTestPreComposition,
268        preCompositionSetsNeedsAnotherUpdateIfAtLeastOneLayerRequestsIt) {
269     EXPECT_CALL(*mLayer1FE, onPreComposition(_)).WillOnce(Return(true));
270     EXPECT_CALL(*mLayer2FE, onPreComposition(_)).WillOnce(Return(false));
271     EXPECT_CALL(*mLayer3FE, onPreComposition(_)).WillOnce(Return(false));
272 
273     mRefreshArgs.outputs = {mOutput1};
274     mRefreshArgs.layers = {mLayer1FE, mLayer2FE, mLayer3FE};
275 
276     mEngine.preComposition(mRefreshArgs);
277 
278     EXPECT_TRUE(mEngine.needsAnotherUpdate());
279 }
280 
281 struct CompositionEngineOffloadTest : public testing::Test {
282     impl::CompositionEngine mEngine;
283     CompositionRefreshArgs mRefreshArgs;
284 
285     std::shared_ptr<mock::Output> mDisplay1{std::make_shared<StrictMock<mock::Output>>()};
286     std::shared_ptr<mock::Output> mDisplay2{std::make_shared<StrictMock<mock::Output>>()};
287     std::shared_ptr<mock::Output> mVirtualDisplay{std::make_shared<StrictMock<mock::Output>>()};
288     std::shared_ptr<mock::Output> mHalVirtualDisplay{std::make_shared<StrictMock<mock::Output>>()};
289 
290     static constexpr PhysicalDisplayId kDisplayId1 = PhysicalDisplayId::fromPort(123u);
291     static constexpr PhysicalDisplayId kDisplayId2 = PhysicalDisplayId::fromPort(234u);
292     static constexpr GpuVirtualDisplayId kGpuVirtualDisplayId{789u};
293     static constexpr HalVirtualDisplayId kHalVirtualDisplayId{456u};
294 
295     std::array<impl::OutputCompositionState, 4> mOutputStates;
296 
SetUpandroid::compositionengine::__anon2b52074d0111::CompositionEngineOffloadTest297     void SetUp() override {
298         EXPECT_CALL(*mDisplay1, getDisplayId)
299                 .WillRepeatedly(Return(std::make_optional<DisplayId>(kDisplayId1)));
300         EXPECT_CALL(*mDisplay2, getDisplayId)
301                 .WillRepeatedly(Return(std::make_optional<DisplayId>(kDisplayId2)));
302         EXPECT_CALL(*mVirtualDisplay, getDisplayId)
303                 .WillRepeatedly(Return(std::make_optional<DisplayId>(kGpuVirtualDisplayId)));
304         EXPECT_CALL(*mHalVirtualDisplay, getDisplayId)
305                 .WillRepeatedly(Return(std::make_optional<DisplayId>(kHalVirtualDisplayId)));
306 
307         // Most tests will depend on the outputs being enabled.
308         for (auto& state : mOutputStates) {
309             state.isEnabled = true;
310         }
311 
312         EXPECT_CALL(*mDisplay1, getState).WillRepeatedly(ReturnRef(mOutputStates[0]));
313         EXPECT_CALL(*mDisplay2, getState).WillRepeatedly(ReturnRef(mOutputStates[1]));
314         EXPECT_CALL(*mVirtualDisplay, getState).WillRepeatedly(ReturnRef(mOutputStates[2]));
315         EXPECT_CALL(*mHalVirtualDisplay, getState).WillRepeatedly(ReturnRef(mOutputStates[3]));
316     }
317 
setOutputsandroid::compositionengine::__anon2b52074d0111::CompositionEngineOffloadTest318     void setOutputs(std::initializer_list<std::shared_ptr<mock::Output>> outputs) {
319         for (auto& output : outputs) {
320             // If we call mEngine.present, prepare and present will be called on all the
321             // outputs in mRefreshArgs, but that's not the interesting part of the test.
322             EXPECT_CALL(*output, prepare(Ref(mRefreshArgs), _)).Times(1);
323             EXPECT_CALL(*output, present(Ref(mRefreshArgs)))
324                     .WillOnce(Return(ftl::yield<std::monostate>({})));
325 
326             mRefreshArgs.outputs.push_back(std::move(output));
327         }
328     }
329 };
330 
TEST_F(CompositionEngineOffloadTest,basic)331 TEST_F(CompositionEngineOffloadTest, basic) {
332     EXPECT_CALL(*mDisplay1, supportsOffloadPresent).WillOnce(Return(true));
333     EXPECT_CALL(*mDisplay2, supportsOffloadPresent).WillOnce(Return(true));
334 
335     EXPECT_CALL(*mDisplay1, offloadPresentNextFrame).Times(1);
336     EXPECT_CALL(*mDisplay2, offloadPresentNextFrame).Times(0);
337 
338     SET_FLAG_FOR_TEST(flags::multithreaded_present, true);
339     setOutputs({mDisplay1, mDisplay2});
340 
341     mEngine.present(mRefreshArgs);
342 }
343 
TEST_F(CompositionEngineOffloadTest,dependsOnSupport)344 TEST_F(CompositionEngineOffloadTest, dependsOnSupport) {
345     EXPECT_CALL(*mDisplay1, supportsOffloadPresent).WillOnce(Return(false));
346     EXPECT_CALL(*mDisplay2, supportsOffloadPresent).Times(0);
347 
348     EXPECT_CALL(*mDisplay1, offloadPresentNextFrame).Times(0);
349     EXPECT_CALL(*mDisplay2, offloadPresentNextFrame).Times(0);
350 
351     SET_FLAG_FOR_TEST(flags::multithreaded_present, true);
352     setOutputs({mDisplay1, mDisplay2});
353 
354     mEngine.present(mRefreshArgs);
355 }
356 
TEST_F(CompositionEngineOffloadTest,dependsOnSupport2)357 TEST_F(CompositionEngineOffloadTest, dependsOnSupport2) {
358     EXPECT_CALL(*mDisplay1, supportsOffloadPresent).WillOnce(Return(true));
359     EXPECT_CALL(*mDisplay2, supportsOffloadPresent).WillOnce(Return(false));
360 
361     EXPECT_CALL(*mDisplay1, offloadPresentNextFrame).Times(0);
362     EXPECT_CALL(*mDisplay2, offloadPresentNextFrame).Times(0);
363 
364     SET_FLAG_FOR_TEST(flags::multithreaded_present, true);
365     setOutputs({mDisplay1, mDisplay2});
366 
367     mEngine.present(mRefreshArgs);
368 }
369 
TEST_F(CompositionEngineOffloadTest,dependsOnFlag)370 TEST_F(CompositionEngineOffloadTest, dependsOnFlag) {
371     EXPECT_CALL(*mDisplay1, supportsOffloadPresent).Times(0);
372     EXPECT_CALL(*mDisplay2, supportsOffloadPresent).Times(0);
373 
374     EXPECT_CALL(*mDisplay1, offloadPresentNextFrame).Times(0);
375     EXPECT_CALL(*mDisplay2, offloadPresentNextFrame).Times(0);
376 
377     SET_FLAG_FOR_TEST(flags::multithreaded_present, false);
378     setOutputs({mDisplay1, mDisplay2});
379 
380     mEngine.present(mRefreshArgs);
381 }
382 
TEST_F(CompositionEngineOffloadTest,oneDisplay)383 TEST_F(CompositionEngineOffloadTest, oneDisplay) {
384     EXPECT_CALL(*mDisplay1, supportsOffloadPresent).Times(0);
385 
386     EXPECT_CALL(*mDisplay1, offloadPresentNextFrame).Times(0);
387 
388     SET_FLAG_FOR_TEST(flags::multithreaded_present, true);
389     setOutputs({mDisplay1});
390 
391     mEngine.present(mRefreshArgs);
392 }
393 
TEST_F(CompositionEngineOffloadTest,virtualDisplay)394 TEST_F(CompositionEngineOffloadTest, virtualDisplay) {
395     EXPECT_CALL(*mDisplay1, supportsOffloadPresent).WillOnce(Return(true));
396     EXPECT_CALL(*mDisplay2, supportsOffloadPresent).WillOnce(Return(true));
397     EXPECT_CALL(*mVirtualDisplay, supportsOffloadPresent).Times(0);
398 
399     EXPECT_CALL(*mDisplay1, offloadPresentNextFrame).Times(1);
400     EXPECT_CALL(*mDisplay2, offloadPresentNextFrame).Times(0);
401     EXPECT_CALL(*mVirtualDisplay, offloadPresentNextFrame).Times(0);
402 
403     SET_FLAG_FOR_TEST(flags::multithreaded_present, true);
404     setOutputs({mDisplay1, mDisplay2, mVirtualDisplay});
405 
406     mEngine.present(mRefreshArgs);
407 }
408 
TEST_F(CompositionEngineOffloadTest,virtualDisplay2)409 TEST_F(CompositionEngineOffloadTest, virtualDisplay2) {
410     EXPECT_CALL(*mDisplay1, supportsOffloadPresent).WillOnce(Return(true));
411     EXPECT_CALL(*mVirtualDisplay, supportsOffloadPresent).Times(0);
412 
413     EXPECT_CALL(*mDisplay1, offloadPresentNextFrame).Times(0);
414     EXPECT_CALL(*mVirtualDisplay, offloadPresentNextFrame).Times(0);
415 
416     SET_FLAG_FOR_TEST(flags::multithreaded_present, true);
417     setOutputs({mDisplay1, mVirtualDisplay});
418 
419     mEngine.present(mRefreshArgs);
420 }
421 
TEST_F(CompositionEngineOffloadTest,halVirtual)422 TEST_F(CompositionEngineOffloadTest, halVirtual) {
423     EXPECT_CALL(*mDisplay1, supportsOffloadPresent).WillOnce(Return(true));
424     EXPECT_CALL(*mHalVirtualDisplay, supportsOffloadPresent).WillOnce(Return(true));
425 
426     EXPECT_CALL(*mDisplay1, offloadPresentNextFrame).Times(1);
427     EXPECT_CALL(*mHalVirtualDisplay, offloadPresentNextFrame).Times(0);
428 
429     SET_FLAG_FOR_TEST(flags::multithreaded_present, true);
430     setOutputs({mDisplay1, mHalVirtualDisplay});
431 
432     mEngine.present(mRefreshArgs);
433 }
434 
TEST_F(CompositionEngineOffloadTest,ordering)435 TEST_F(CompositionEngineOffloadTest, ordering) {
436     EXPECT_CALL(*mVirtualDisplay, supportsOffloadPresent).Times(0);
437     EXPECT_CALL(*mHalVirtualDisplay, supportsOffloadPresent).WillOnce(Return(true));
438     EXPECT_CALL(*mDisplay1, supportsOffloadPresent).WillOnce(Return(true));
439     EXPECT_CALL(*mDisplay2, supportsOffloadPresent).WillOnce(Return(true));
440 
441     EXPECT_CALL(*mVirtualDisplay, offloadPresentNextFrame).Times(0);
442     EXPECT_CALL(*mHalVirtualDisplay, offloadPresentNextFrame).Times(1);
443     EXPECT_CALL(*mDisplay1, offloadPresentNextFrame).Times(1);
444     EXPECT_CALL(*mDisplay2, offloadPresentNextFrame).Times(0);
445 
446     SET_FLAG_FOR_TEST(flags::multithreaded_present, true);
447     setOutputs({mVirtualDisplay, mHalVirtualDisplay, mDisplay1, mDisplay2});
448 
449     mEngine.present(mRefreshArgs);
450 }
451 
TEST_F(CompositionEngineOffloadTest,dependsOnEnabled)452 TEST_F(CompositionEngineOffloadTest, dependsOnEnabled) {
453     // Disable mDisplay2.
454     mOutputStates[1].isEnabled = false;
455     EXPECT_CALL(*mDisplay1, supportsOffloadPresent).WillOnce(Return(true));
456 
457     // This is not actually called, because it is not enabled, but this distinguishes
458     // from the case where it did not return true.
459     EXPECT_CALL(*mDisplay2, supportsOffloadPresent).WillRepeatedly(Return(true));
460 
461     EXPECT_CALL(*mDisplay1, offloadPresentNextFrame).Times(0);
462     EXPECT_CALL(*mDisplay2, offloadPresentNextFrame).Times(0);
463 
464     SET_FLAG_FOR_TEST(flags::multithreaded_present, true);
465     setOutputs({mDisplay1, mDisplay2});
466 
467     mEngine.present(mRefreshArgs);
468 }
469 
TEST_F(CompositionEngineOffloadTest,disabledDisplaysDoNotPreventOthersFromOffloading)470 TEST_F(CompositionEngineOffloadTest, disabledDisplaysDoNotPreventOthersFromOffloading) {
471     // Disable mDisplay2.
472     mOutputStates[1].isEnabled = false;
473     EXPECT_CALL(*mDisplay1, supportsOffloadPresent).WillOnce(Return(true));
474 
475     // This is not actually called, because it is not enabled, but this distinguishes
476     // from the case where it did not return true.
477     EXPECT_CALL(*mDisplay2, supportsOffloadPresent).WillRepeatedly(Return(true));
478     EXPECT_CALL(*mHalVirtualDisplay, supportsOffloadPresent).WillOnce(Return(true));
479 
480     EXPECT_CALL(*mDisplay1, offloadPresentNextFrame).Times(1);
481     EXPECT_CALL(*mDisplay2, offloadPresentNextFrame).Times(0);
482     EXPECT_CALL(*mHalVirtualDisplay, offloadPresentNextFrame).Times(0);
483 
484     SET_FLAG_FOR_TEST(flags::multithreaded_present, true);
485     setOutputs({mDisplay1, mDisplay2, mHalVirtualDisplay});
486 
487     mEngine.present(mRefreshArgs);
488 }
489 
490 struct CompositionEnginePostCompositionTest : public CompositionEngineTest {
491     sp<StrictMock<mock::LayerFE>> mLayer1FE = sp<StrictMock<mock::LayerFE>>::make();
492     sp<StrictMock<mock::LayerFE>> mLayer2FE = sp<StrictMock<mock::LayerFE>>::make();
493     sp<StrictMock<mock::LayerFE>> mLayer3FE = sp<StrictMock<mock::LayerFE>>::make();
494 };
495 
TEST_F(CompositionEnginePostCompositionTest,postCompositionReleasesAllFences)496 TEST_F(CompositionEnginePostCompositionTest, postCompositionReleasesAllFences) {
497     SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::ce_fence_promise, true);
498     ASSERT_TRUE(FlagManager::getInstance().ce_fence_promise());
499 
500     EXPECT_CALL(*mLayer1FE, getReleaseFencePromiseStatus)
501             .WillOnce(Return(LayerFE::ReleaseFencePromiseStatus::FULFILLED));
502     EXPECT_CALL(*mLayer2FE, getReleaseFencePromiseStatus)
503             .WillOnce(Return(LayerFE::ReleaseFencePromiseStatus::FULFILLED));
504     EXPECT_CALL(*mLayer3FE, getReleaseFencePromiseStatus)
505             .WillOnce(Return(LayerFE::ReleaseFencePromiseStatus::INITIALIZED));
506     mRefreshArgs.layers = {mLayer1FE, mLayer2FE, mLayer3FE};
507 
508     EXPECT_CALL(*mLayer1FE, setReleaseFence(_)).Times(0);
509     EXPECT_CALL(*mLayer2FE, setReleaseFence(_)).Times(0);
510     EXPECT_CALL(*mLayer3FE, setReleaseFence(_)).Times(1);
511 
512     mEngine.postComposition(mRefreshArgs);
513 }
514 } // namespace
515 } // namespace android::compositionengine
516