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