• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <compositionengine/CompositionRefreshArgs.h>
18 #include <compositionengine/LayerFECompositionState.h>
19 #include <compositionengine/impl/CompositionEngine.h>
20 #include <compositionengine/mock/LayerFE.h>
21 #include <compositionengine/mock/Output.h>
22 #include <compositionengine/mock/OutputLayer.h>
23 #include <gtest/gtest.h>
24 #include <renderengine/mock/RenderEngine.h>
25 
26 #include "MockHWComposer.h"
27 #include "TimeStats/TimeStats.h"
28 
29 namespace android::compositionengine {
30 namespace {
31 
32 using ::testing::_;
33 using ::testing::DoAll;
34 using ::testing::InSequence;
35 using ::testing::Ref;
36 using ::testing::Return;
37 using ::testing::ReturnRef;
38 using ::testing::SaveArg;
39 using ::testing::StrictMock;
40 
41 struct CompositionEngineTest : public testing::Test {
42     std::shared_ptr<TimeStats> mTimeStats;
43 
44     impl::CompositionEngine mEngine;
45     CompositionRefreshArgs mRefreshArgs;
46 
47     std::shared_ptr<mock::Output> mOutput1{std::make_shared<StrictMock<mock::Output>>()};
48     std::shared_ptr<mock::Output> mOutput2{std::make_shared<StrictMock<mock::Output>>()};
49     std::shared_ptr<mock::Output> mOutput3{std::make_shared<StrictMock<mock::Output>>()};
50 };
51 
TEST_F(CompositionEngineTest,canInstantiateCompositionEngine)52 TEST_F(CompositionEngineTest, canInstantiateCompositionEngine) {
53     auto engine = impl::createCompositionEngine();
54     EXPECT_TRUE(engine.get() != nullptr);
55 }
56 
TEST_F(CompositionEngineTest,canSetHWComposer)57 TEST_F(CompositionEngineTest, canSetHWComposer) {
58     android::mock::HWComposer* hwc = new StrictMock<android::mock::HWComposer>();
59     mEngine.setHwComposer(std::unique_ptr<android::HWComposer>(hwc));
60 
61     EXPECT_EQ(hwc, &mEngine.getHwComposer());
62 }
63 
TEST_F(CompositionEngineTest,canSetRenderEngine)64 TEST_F(CompositionEngineTest, canSetRenderEngine) {
65     renderengine::mock::RenderEngine* renderEngine =
66             new StrictMock<renderengine::mock::RenderEngine>();
67     mEngine.setRenderEngine(std::unique_ptr<renderengine::RenderEngine>(renderEngine));
68 
69     EXPECT_EQ(renderEngine, &mEngine.getRenderEngine());
70 }
71 
TEST_F(CompositionEngineTest,canSetTimeStats)72 TEST_F(CompositionEngineTest, canSetTimeStats) {
73     mEngine.setTimeStats(mTimeStats);
74 
75     EXPECT_EQ(mTimeStats.get(), &mEngine.getTimeStats());
76 }
77 
78 /*
79  * CompositionEngine::present
80  */
81 
82 struct CompositionEnginePresentTest : public CompositionEngineTest {
83     struct CompositionEnginePartialMock : public impl::CompositionEngine {
84         // These are the overridable functions CompositionEngine::present() may
85         // call, and have separate test coverage.
86         MOCK_METHOD1(preComposition, void(CompositionRefreshArgs&));
87     };
88 
89     StrictMock<CompositionEnginePartialMock> mEngine;
90 };
91 
TEST_F(CompositionEnginePresentTest,worksWithEmptyRequest)92 TEST_F(CompositionEnginePresentTest, worksWithEmptyRequest) {
93     // present() always calls preComposition()
94     EXPECT_CALL(mEngine, preComposition(Ref(mRefreshArgs)));
95 
96     mEngine.present(mRefreshArgs);
97 }
98 
TEST_F(CompositionEnginePresentTest,worksAsExpected)99 TEST_F(CompositionEnginePresentTest, worksAsExpected) {
100     // Expect calls to in a certain sequence
101     InSequence seq;
102 
103     // present() always calls preComposition()
104     EXPECT_CALL(mEngine, preComposition(Ref(mRefreshArgs)));
105 
106     // The first step in presenting is to make sure all outputs are prepared.
107     EXPECT_CALL(*mOutput1, prepare(Ref(mRefreshArgs), _));
108     EXPECT_CALL(*mOutput2, prepare(Ref(mRefreshArgs), _));
109     EXPECT_CALL(*mOutput3, prepare(Ref(mRefreshArgs), _));
110 
111     // The next step in presenting is to make sure all outputs have the latest
112     // state from the front-end (SurfaceFlinger).
113     EXPECT_CALL(*mOutput1, updateLayerStateFromFE(Ref(mRefreshArgs)));
114     EXPECT_CALL(*mOutput2, updateLayerStateFromFE(Ref(mRefreshArgs)));
115     EXPECT_CALL(*mOutput3, updateLayerStateFromFE(Ref(mRefreshArgs)));
116 
117     // The last step is to actually present each output.
118     EXPECT_CALL(*mOutput1, present(Ref(mRefreshArgs)));
119     EXPECT_CALL(*mOutput2, present(Ref(mRefreshArgs)));
120     EXPECT_CALL(*mOutput3, present(Ref(mRefreshArgs)));
121 
122     mRefreshArgs.outputs = {mOutput1, mOutput2, mOutput3};
123     mEngine.present(mRefreshArgs);
124 }
125 
126 /*
127  * CompositionEngine::updateCursorAsync
128  */
129 
130 struct CompositionEngineUpdateCursorAsyncTest : public CompositionEngineTest {
131 public:
132     struct Layer {
Layerandroid::compositionengine::__anonae99e3d40111::CompositionEngineUpdateCursorAsyncTest::Layer133         Layer() { EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE)); }
134 
135         StrictMock<mock::OutputLayer> outputLayer;
136         sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
137         LayerFECompositionState layerFEState;
138     };
139 
CompositionEngineUpdateCursorAsyncTestandroid::compositionengine::__anonae99e3d40111::CompositionEngineUpdateCursorAsyncTest140     CompositionEngineUpdateCursorAsyncTest() {
141         EXPECT_CALL(*mOutput1, getOutputLayerCount()).WillRepeatedly(Return(0u));
142         EXPECT_CALL(*mOutput1, getOutputLayerOrderedByZByIndex(_)).Times(0);
143 
144         EXPECT_CALL(*mOutput2, getOutputLayerCount()).WillRepeatedly(Return(1u));
145         EXPECT_CALL(*mOutput2, getOutputLayerOrderedByZByIndex(0))
146                 .WillRepeatedly(Return(&mOutput2Layer1.outputLayer));
147 
148         EXPECT_CALL(*mOutput3, getOutputLayerCount()).WillRepeatedly(Return(2u));
149         EXPECT_CALL(*mOutput3, getOutputLayerOrderedByZByIndex(0))
150                 .WillRepeatedly(Return(&mOutput3Layer1.outputLayer));
151         EXPECT_CALL(*mOutput3, getOutputLayerOrderedByZByIndex(1))
152                 .WillRepeatedly(Return(&mOutput3Layer2.outputLayer));
153     }
154 
155     Layer mOutput2Layer1;
156     Layer mOutput3Layer1;
157     Layer mOutput3Layer2;
158 };
159 
TEST_F(CompositionEngineUpdateCursorAsyncTest,handlesNoOutputs)160 TEST_F(CompositionEngineUpdateCursorAsyncTest, handlesNoOutputs) {
161     mEngine.updateCursorAsync(mRefreshArgs);
162 }
163 
TEST_F(CompositionEngineUpdateCursorAsyncTest,handlesNoLayersBeingCursorLayers)164 TEST_F(CompositionEngineUpdateCursorAsyncTest, handlesNoLayersBeingCursorLayers) {
165     EXPECT_CALL(mOutput3Layer1.outputLayer, isHardwareCursor()).WillRepeatedly(Return(false));
166     EXPECT_CALL(mOutput3Layer2.outputLayer, isHardwareCursor()).WillRepeatedly(Return(false));
167     EXPECT_CALL(mOutput2Layer1.outputLayer, isHardwareCursor()).WillRepeatedly(Return(false));
168 
169     mRefreshArgs.outputs = {mOutput1, mOutput2, mOutput3};
170 
171     mEngine.updateCursorAsync(mRefreshArgs);
172 }
173 
TEST_F(CompositionEngineUpdateCursorAsyncTest,handlesMultipleLayersBeingCursorLayers)174 TEST_F(CompositionEngineUpdateCursorAsyncTest, handlesMultipleLayersBeingCursorLayers) {
175     {
176         InSequence seq;
177         EXPECT_CALL(mOutput2Layer1.outputLayer, isHardwareCursor()).WillRepeatedly(Return(true));
178         EXPECT_CALL(*mOutput2Layer1.layerFE, prepareCompositionState(LayerFE::StateSubset::Cursor));
179         EXPECT_CALL(mOutput2Layer1.outputLayer, writeCursorPositionToHWC());
180     }
181 
182     {
183         InSequence seq;
184         EXPECT_CALL(mOutput3Layer1.outputLayer, isHardwareCursor()).WillRepeatedly(Return(true));
185         EXPECT_CALL(*mOutput3Layer1.layerFE, prepareCompositionState(LayerFE::StateSubset::Cursor));
186         EXPECT_CALL(mOutput3Layer1.outputLayer, writeCursorPositionToHWC());
187     }
188 
189     {
190         InSequence seq;
191         EXPECT_CALL(mOutput3Layer2.outputLayer, isHardwareCursor()).WillRepeatedly(Return(true));
192         EXPECT_CALL(*mOutput3Layer2.layerFE, prepareCompositionState(LayerFE::StateSubset::Cursor));
193         EXPECT_CALL(mOutput3Layer2.outputLayer, writeCursorPositionToHWC());
194     }
195 
196     mRefreshArgs.outputs = {mOutput1, mOutput2, mOutput3};
197 
198     mEngine.updateCursorAsync(mRefreshArgs);
199 }
200 
201 /*
202  * CompositionEngine::preComposition
203  */
204 
205 struct CompositionTestPreComposition : public CompositionEngineTest {
206     sp<StrictMock<mock::LayerFE>> mLayer1FE{new StrictMock<mock::LayerFE>()};
207     sp<StrictMock<mock::LayerFE>> mLayer2FE{new StrictMock<mock::LayerFE>()};
208     sp<StrictMock<mock::LayerFE>> mLayer3FE{new StrictMock<mock::LayerFE>()};
209 };
210 
TEST_F(CompositionTestPreComposition,preCompositionSetsFrameTimestamp)211 TEST_F(CompositionTestPreComposition, preCompositionSetsFrameTimestamp) {
212     const nsecs_t before = systemTime(SYSTEM_TIME_MONOTONIC);
213     mEngine.preComposition(mRefreshArgs);
214     const nsecs_t after = systemTime(SYSTEM_TIME_MONOTONIC);
215 
216     // The frame timestamp should be between the before and after timestamps
217     EXPECT_GE(mEngine.getLastFrameRefreshTimestamp(), before);
218     EXPECT_LE(mEngine.getLastFrameRefreshTimestamp(), after);
219 }
220 
TEST_F(CompositionTestPreComposition,preCompositionInvokesLayerPreCompositionWithFrameTimestamp)221 TEST_F(CompositionTestPreComposition, preCompositionInvokesLayerPreCompositionWithFrameTimestamp) {
222     nsecs_t ts1 = 0;
223     nsecs_t ts2 = 0;
224     nsecs_t ts3 = 0;
225     EXPECT_CALL(*mLayer1FE, onPreComposition(_)).WillOnce(DoAll(SaveArg<0>(&ts1), Return(false)));
226     EXPECT_CALL(*mLayer2FE, onPreComposition(_)).WillOnce(DoAll(SaveArg<0>(&ts2), Return(false)));
227     EXPECT_CALL(*mLayer3FE, onPreComposition(_)).WillOnce(DoAll(SaveArg<0>(&ts3), Return(false)));
228 
229     mRefreshArgs.outputs = {mOutput1};
230     mRefreshArgs.layers = {mLayer1FE, mLayer2FE, mLayer3FE};
231 
232     mEngine.preComposition(mRefreshArgs);
233 
234     // Each of the onPreComposition calls should used the same refresh timestamp
235     EXPECT_EQ(ts1, mEngine.getLastFrameRefreshTimestamp());
236     EXPECT_EQ(ts2, mEngine.getLastFrameRefreshTimestamp());
237     EXPECT_EQ(ts3, mEngine.getLastFrameRefreshTimestamp());
238 }
239 
TEST_F(CompositionTestPreComposition,preCompositionDefaultsToNoUpdateNeeded)240 TEST_F(CompositionTestPreComposition, preCompositionDefaultsToNoUpdateNeeded) {
241     EXPECT_CALL(*mLayer1FE, onPreComposition(_)).WillOnce(Return(false));
242     EXPECT_CALL(*mLayer2FE, onPreComposition(_)).WillOnce(Return(false));
243     EXPECT_CALL(*mLayer3FE, onPreComposition(_)).WillOnce(Return(false));
244 
245     mEngine.setNeedsAnotherUpdateForTest(true);
246 
247     mRefreshArgs.outputs = {mOutput1};
248     mRefreshArgs.layers = {mLayer1FE, mLayer2FE, mLayer3FE};
249 
250     mEngine.preComposition(mRefreshArgs);
251 
252     // The call should have cleared the needsAnotherUpdate flag
253     EXPECT_FALSE(mEngine.needsAnotherUpdate());
254 }
255 
TEST_F(CompositionTestPreComposition,preCompositionSetsNeedsAnotherUpdateIfAtLeastOneLayerRequestsIt)256 TEST_F(CompositionTestPreComposition,
257        preCompositionSetsNeedsAnotherUpdateIfAtLeastOneLayerRequestsIt) {
258     EXPECT_CALL(*mLayer1FE, onPreComposition(_)).WillOnce(Return(true));
259     EXPECT_CALL(*mLayer2FE, onPreComposition(_)).WillOnce(Return(false));
260     EXPECT_CALL(*mLayer3FE, onPreComposition(_)).WillOnce(Return(false));
261 
262     mRefreshArgs.outputs = {mOutput1};
263     mRefreshArgs.layers = {mLayer1FE, mLayer2FE, mLayer3FE};
264 
265     mEngine.preComposition(mRefreshArgs);
266 
267     EXPECT_TRUE(mEngine.needsAnotherUpdate());
268 }
269 
270 } // namespace
271 } // namespace android::compositionengine
272