blob: c1faa901ae9b1d469a3670bdbbd355138d05f8c9 [file] [log] [blame]
Lloyd Pique70d91362018-10-18 16:02:55 -07001/*
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
Lloyd Piqueab039b52019-02-13 14:22:42 -080017#include <compositionengine/CompositionRefreshArgs.h>
Lloyd Piqueaed56ab2019-11-13 22:34:11 -080018#include <compositionengine/LayerFECompositionState.h>
Lloyd Pique70d91362018-10-18 16:02:55 -070019#include <compositionengine/impl/CompositionEngine.h>
Lloyd Piqueab039b52019-02-13 14:22:42 -080020#include <compositionengine/mock/Layer.h>
21#include <compositionengine/mock/LayerFE.h>
22#include <compositionengine/mock/Output.h>
Lloyd Piqueaed56ab2019-11-13 22:34:11 -080023#include <compositionengine/mock/OutputLayer.h>
Lloyd Pique70d91362018-10-18 16:02:55 -070024#include <gtest/gtest.h>
Lloyd Piqueb97e04f2018-10-18 17:07:05 -070025#include <renderengine/mock/RenderEngine.h>
Lloyd Pique70d91362018-10-18 16:02:55 -070026
Lloyd Pique441d5042018-10-18 16:49:51 -070027#include "MockHWComposer.h"
Alec Mourie4034bb2019-11-19 12:45:54 -080028#include "TimeStats/TimeStats.h"
Lloyd Pique441d5042018-10-18 16:49:51 -070029
Lloyd Pique70d91362018-10-18 16:02:55 -070030namespace android::compositionengine {
31namespace {
32
Lloyd Piqueab039b52019-02-13 14:22:42 -080033using ::testing::_;
Lloyd Piquee82ed2d2019-11-13 19:28:12 -080034using ::testing::InSequence;
35using ::testing::Ref;
Lloyd Piqueab039b52019-02-13 14:22:42 -080036using ::testing::Return;
Lloyd Piqueaed56ab2019-11-13 22:34:11 -080037using ::testing::ReturnRef;
Lloyd Piqueab039b52019-02-13 14:22:42 -080038using ::testing::SaveArg;
Lloyd Pique441d5042018-10-18 16:49:51 -070039using ::testing::StrictMock;
40
Lloyd Piquee82ed2d2019-11-13 19:28:12 -080041struct CompositionEngineTest : public testing::Test {
Lloyd Piqueab039b52019-02-13 14:22:42 -080042 android::mock::HWComposer* mHwc = new StrictMock<android::mock::HWComposer>();
Lloyd Piqueb97e04f2018-10-18 17:07:05 -070043 renderengine::mock::RenderEngine* mRenderEngine =
44 new StrictMock<renderengine::mock::RenderEngine>();
Alec Mourie4034bb2019-11-19 12:45:54 -080045 std::shared_ptr<TimeStats> mTimeStats;
46
Lloyd Pique441d5042018-10-18 16:49:51 -070047 impl::CompositionEngine mEngine;
Lloyd Piquee82ed2d2019-11-13 19:28:12 -080048 CompositionRefreshArgs mRefreshArgs;
49
50 std::shared_ptr<mock::Output> mOutput1{std::make_shared<StrictMock<mock::Output>>()};
51 std::shared_ptr<mock::Output> mOutput2{std::make_shared<StrictMock<mock::Output>>()};
52 std::shared_ptr<mock::Output> mOutput3{std::make_shared<StrictMock<mock::Output>>()};
53
54 std::shared_ptr<mock::Layer> mLayer1{std::make_shared<StrictMock<mock::Layer>>()};
55 std::shared_ptr<mock::Layer> mLayer2{std::make_shared<StrictMock<mock::Layer>>()};
56 std::shared_ptr<mock::Layer> mLayer3{std::make_shared<StrictMock<mock::Layer>>()};
57 std::shared_ptr<mock::Layer> mLayer4{std::make_shared<StrictMock<mock::Layer>>()};
Lloyd Pique70d91362018-10-18 16:02:55 -070058};
59
Lloyd Pique70d91362018-10-18 16:02:55 -070060TEST_F(CompositionEngineTest, canInstantiateCompositionEngine) {
61 auto engine = impl::createCompositionEngine();
62 EXPECT_TRUE(engine.get() != nullptr);
63}
64
Lloyd Pique441d5042018-10-18 16:49:51 -070065TEST_F(CompositionEngineTest, canSetHWComposer) {
66 mEngine.setHwComposer(std::unique_ptr<android::HWComposer>(mHwc));
67
68 EXPECT_EQ(mHwc, &mEngine.getHwComposer());
69}
70
Lloyd Piqueb97e04f2018-10-18 17:07:05 -070071TEST_F(CompositionEngineTest, canSetRenderEngine) {
72 mEngine.setRenderEngine(std::unique_ptr<renderengine::RenderEngine>(mRenderEngine));
73
74 EXPECT_EQ(mRenderEngine, &mEngine.getRenderEngine());
75}
76
Alec Mourie4034bb2019-11-19 12:45:54 -080077TEST_F(CompositionEngineTest, canSetTimeStats) {
78 mEngine.setTimeStats(mTimeStats);
79
80 EXPECT_EQ(mTimeStats.get(), &mEngine.getTimeStats());
81}
82
Lloyd Piqueab039b52019-02-13 14:22:42 -080083/*
Lloyd Piquee82ed2d2019-11-13 19:28:12 -080084 * CompositionEngine::present
85 */
86
87struct CompositionEnginePresentTest : public CompositionEngineTest {
88 struct CompositionEnginePartialMock : public impl::CompositionEngine {
89 // These are the overridable functions CompositionEngine::present() may
90 // call, and have separate test coverage.
91 MOCK_METHOD1(preComposition, void(CompositionRefreshArgs&));
92 };
93
94 StrictMock<CompositionEnginePartialMock> mEngine;
95};
96
97TEST_F(CompositionEnginePresentTest, worksWithEmptyRequest) {
98 // present() always calls preComposition()
99 EXPECT_CALL(mEngine, preComposition(Ref(mRefreshArgs)));
100
101 mEngine.present(mRefreshArgs);
102}
103
104TEST_F(CompositionEnginePresentTest, worksAsExpected) {
105 // Expect calls to in a certain sequence
106 InSequence seq;
107
108 // present() always calls preComposition()
109 EXPECT_CALL(mEngine, preComposition(Ref(mRefreshArgs)));
110
111 // The first step in presenting is to make sure all outputs are prepared.
112 EXPECT_CALL(*mOutput1, prepare(Ref(mRefreshArgs), _));
113 EXPECT_CALL(*mOutput2, prepare(Ref(mRefreshArgs), _));
114 EXPECT_CALL(*mOutput3, prepare(Ref(mRefreshArgs), _));
115
116 // The next step in presenting is to make sure all outputs have the latest
117 // state from the front-end (SurfaceFlinger).
118 EXPECT_CALL(*mOutput1, updateLayerStateFromFE(Ref(mRefreshArgs)));
119 EXPECT_CALL(*mOutput2, updateLayerStateFromFE(Ref(mRefreshArgs)));
120 EXPECT_CALL(*mOutput3, updateLayerStateFromFE(Ref(mRefreshArgs)));
121
122 // The last step is to actually present each output.
123 EXPECT_CALL(*mOutput1, present(Ref(mRefreshArgs)));
124 EXPECT_CALL(*mOutput2, present(Ref(mRefreshArgs)));
125 EXPECT_CALL(*mOutput3, present(Ref(mRefreshArgs)));
126
127 mRefreshArgs.outputs = {mOutput1, mOutput2, mOutput3};
128 mEngine.present(mRefreshArgs);
129}
130
131/*
Lloyd Piqueaed56ab2019-11-13 22:34:11 -0800132 * CompositionEngine::updateCursorAsync
133 */
134
135struct CompositionEngineUpdateCursorAsyncTest : public CompositionEngineTest {
136public:
137 CompositionEngineUpdateCursorAsyncTest() {
Lloyd Pique0a456232020-01-16 17:51:13 -0800138 EXPECT_CALL(*mOutput1, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Piqueaed56ab2019-11-13 22:34:11 -0800139 EXPECT_CALL(*mOutput1, getOutputLayerOrderedByZByIndex(_)).Times(0);
140
Lloyd Pique0a456232020-01-16 17:51:13 -0800141 EXPECT_CALL(*mOutput2, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Piqueaed56ab2019-11-13 22:34:11 -0800142 EXPECT_CALL(*mOutput2, getOutputLayerOrderedByZByIndex(0))
143 .WillRepeatedly(Return(&mOutput2OutputLayer1));
144
Lloyd Pique0a456232020-01-16 17:51:13 -0800145 EXPECT_CALL(*mOutput3, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Piqueaed56ab2019-11-13 22:34:11 -0800146 EXPECT_CALL(*mOutput3, getOutputLayerOrderedByZByIndex(0))
147 .WillRepeatedly(Return(&mOutput3OutputLayer1));
148 EXPECT_CALL(*mOutput3, getOutputLayerOrderedByZByIndex(1))
149 .WillRepeatedly(Return(&mOutput3OutputLayer2));
150
151 EXPECT_CALL(mOutput2OutputLayer1, getLayerFE()).WillRepeatedly(ReturnRef(mOutput2Layer1FE));
152 EXPECT_CALL(mOutput3OutputLayer1, getLayerFE()).WillRepeatedly(ReturnRef(mOutput3Layer1FE));
153 EXPECT_CALL(mOutput3OutputLayer2, getLayerFE()).WillRepeatedly(ReturnRef(mOutput3Layer2FE));
154
155 EXPECT_CALL(mOutput2OutputLayer1, getLayer()).WillRepeatedly(ReturnRef(mOutput2Layer1));
156 EXPECT_CALL(mOutput3OutputLayer1, getLayer()).WillRepeatedly(ReturnRef(mOutput3Layer1));
157 EXPECT_CALL(mOutput3OutputLayer2, getLayer()).WillRepeatedly(ReturnRef(mOutput3Layer2));
158
159 EXPECT_CALL(mOutput2Layer1, editFEState()).WillRepeatedly(ReturnRef(mOutput2Layer1FEState));
160 EXPECT_CALL(mOutput3Layer1, editFEState()).WillRepeatedly(ReturnRef(mOutput3Layer1FEState));
161 EXPECT_CALL(mOutput3Layer2, editFEState()).WillRepeatedly(ReturnRef(mOutput3Layer2FEState));
162 }
163
164 StrictMock<mock::OutputLayer> mOutput2OutputLayer1;
165 StrictMock<mock::OutputLayer> mOutput3OutputLayer1;
166 StrictMock<mock::OutputLayer> mOutput3OutputLayer2;
167
168 StrictMock<mock::LayerFE> mOutput2Layer1FE;
169 StrictMock<mock::LayerFE> mOutput3Layer1FE;
170 StrictMock<mock::LayerFE> mOutput3Layer2FE;
171
172 StrictMock<mock::Layer> mOutput2Layer1;
173 StrictMock<mock::Layer> mOutput3Layer1;
174 StrictMock<mock::Layer> mOutput3Layer2;
175
176 LayerFECompositionState mOutput2Layer1FEState;
177 LayerFECompositionState mOutput3Layer1FEState;
178 LayerFECompositionState mOutput3Layer2FEState;
179};
180
181TEST_F(CompositionEngineUpdateCursorAsyncTest, handlesNoOutputs) {
182 mEngine.updateCursorAsync(mRefreshArgs);
183}
184
185TEST_F(CompositionEngineUpdateCursorAsyncTest, handlesNoLayersBeingCursorLayers) {
186 EXPECT_CALL(mOutput2OutputLayer1, isHardwareCursor()).WillRepeatedly(Return(false));
187 EXPECT_CALL(mOutput3OutputLayer1, isHardwareCursor()).WillRepeatedly(Return(false));
188 EXPECT_CALL(mOutput3OutputLayer2, isHardwareCursor()).WillRepeatedly(Return(false));
189
190 mRefreshArgs.outputs = {mOutput1, mOutput2, mOutput3};
191
192 mEngine.updateCursorAsync(mRefreshArgs);
193}
194
195TEST_F(CompositionEngineUpdateCursorAsyncTest, handlesMultipleLayersBeingCursorLayers) {
196 {
197 InSequence seq;
198 EXPECT_CALL(mOutput2OutputLayer1, isHardwareCursor()).WillRepeatedly(Return(true));
199 EXPECT_CALL(mOutput2Layer1FE, latchCursorCompositionState(Ref(mOutput2Layer1FEState)));
200 EXPECT_CALL(mOutput2OutputLayer1, writeCursorPositionToHWC());
201 }
202
203 {
204 InSequence seq;
205 EXPECT_CALL(mOutput3OutputLayer1, isHardwareCursor()).WillRepeatedly(Return(true));
206 EXPECT_CALL(mOutput3Layer1FE, latchCursorCompositionState(Ref(mOutput3Layer1FEState)));
207 EXPECT_CALL(mOutput3OutputLayer1, writeCursorPositionToHWC());
208 }
209
210 {
211 InSequence seq;
212 EXPECT_CALL(mOutput3OutputLayer2, isHardwareCursor()).WillRepeatedly(Return(true));
213 EXPECT_CALL(mOutput3Layer2FE, latchCursorCompositionState(Ref(mOutput3Layer2FEState)));
214 EXPECT_CALL(mOutput3OutputLayer2, writeCursorPositionToHWC());
215 }
216
217 mRefreshArgs.outputs = {mOutput1, mOutput2, mOutput3};
218
219 mEngine.updateCursorAsync(mRefreshArgs);
220}
221
222/*
Lloyd Piqueab039b52019-02-13 14:22:42 -0800223 * CompositionEngine::preComposition
224 */
225
Lloyd Piquee82ed2d2019-11-13 19:28:12 -0800226struct CompositionTestPreComposition : public CompositionEngineTest {
227 CompositionTestPreComposition() {
Lloyd Piqueab039b52019-02-13 14:22:42 -0800228 EXPECT_CALL(*mLayer1, getLayerFE()).WillRepeatedly(Return(mLayer1FE));
229 EXPECT_CALL(*mLayer2, getLayerFE()).WillRepeatedly(Return(mLayer2FE));
230 EXPECT_CALL(*mLayer3, getLayerFE()).WillRepeatedly(Return(mLayer3FE));
231 // getLayerFE() can return nullptr. Ensure that this is handled.
232 EXPECT_CALL(*mLayer4, getLayerFE()).WillRepeatedly(Return(nullptr));
Lloyd Piqueab039b52019-02-13 14:22:42 -0800233 }
234
Lloyd Piqueab039b52019-02-13 14:22:42 -0800235 sp<StrictMock<mock::LayerFE>> mLayer1FE{new StrictMock<mock::LayerFE>()};
236 sp<StrictMock<mock::LayerFE>> mLayer2FE{new StrictMock<mock::LayerFE>()};
237 sp<StrictMock<mock::LayerFE>> mLayer3FE{new StrictMock<mock::LayerFE>()};
Lloyd Piqueab039b52019-02-13 14:22:42 -0800238};
239
Lloyd Piquee82ed2d2019-11-13 19:28:12 -0800240TEST_F(CompositionTestPreComposition, preCompositionSetsFrameTimestamp) {
Lloyd Piqueab039b52019-02-13 14:22:42 -0800241 const nsecs_t before = systemTime(SYSTEM_TIME_MONOTONIC);
Lloyd Piquee82ed2d2019-11-13 19:28:12 -0800242 mEngine.preComposition(mRefreshArgs);
Lloyd Piqueab039b52019-02-13 14:22:42 -0800243 const nsecs_t after = systemTime(SYSTEM_TIME_MONOTONIC);
244
245 // The frame timestamp should be between the before and after timestamps
246 EXPECT_GE(mEngine.getLastFrameRefreshTimestamp(), before);
247 EXPECT_LE(mEngine.getLastFrameRefreshTimestamp(), after);
248}
249
Lloyd Piquee82ed2d2019-11-13 19:28:12 -0800250TEST_F(CompositionTestPreComposition, preCompositionInvokesLayerPreCompositionWithFrameTimestamp) {
Lloyd Piqueab039b52019-02-13 14:22:42 -0800251 nsecs_t ts1 = 0;
252 nsecs_t ts2 = 0;
253 nsecs_t ts3 = 0;
254 EXPECT_CALL(*mLayer1FE, onPreComposition(_)).WillOnce(DoAll(SaveArg<0>(&ts1), Return(false)));
255 EXPECT_CALL(*mLayer2FE, onPreComposition(_)).WillOnce(DoAll(SaveArg<0>(&ts2), Return(false)));
256 EXPECT_CALL(*mLayer3FE, onPreComposition(_)).WillOnce(DoAll(SaveArg<0>(&ts3), Return(false)));
257
Lloyd Piquee82ed2d2019-11-13 19:28:12 -0800258 mRefreshArgs.outputs = {mOutput1};
259 mRefreshArgs.layers = {mLayer1, mLayer2, mLayer3, mLayer4};
260
Lloyd Piqueab039b52019-02-13 14:22:42 -0800261 mEngine.preComposition(mRefreshArgs);
262
263 // Each of the onPreComposition calls should used the same refresh timestamp
264 EXPECT_EQ(ts1, mEngine.getLastFrameRefreshTimestamp());
265 EXPECT_EQ(ts2, mEngine.getLastFrameRefreshTimestamp());
266 EXPECT_EQ(ts3, mEngine.getLastFrameRefreshTimestamp());
267}
268
Lloyd Piquee82ed2d2019-11-13 19:28:12 -0800269TEST_F(CompositionTestPreComposition, preCompositionDefaultsToNoUpdateNeeded) {
Lloyd Piqueab039b52019-02-13 14:22:42 -0800270 EXPECT_CALL(*mLayer1FE, onPreComposition(_)).WillOnce(Return(false));
271 EXPECT_CALL(*mLayer2FE, onPreComposition(_)).WillOnce(Return(false));
272 EXPECT_CALL(*mLayer3FE, onPreComposition(_)).WillOnce(Return(false));
273
274 mEngine.setNeedsAnotherUpdateForTest(true);
275
Lloyd Piquee82ed2d2019-11-13 19:28:12 -0800276 mRefreshArgs.outputs = {mOutput1};
277 mRefreshArgs.layers = {mLayer1, mLayer2, mLayer3, mLayer4};
278
Lloyd Piqueab039b52019-02-13 14:22:42 -0800279 mEngine.preComposition(mRefreshArgs);
280
281 // The call should have cleared the needsAnotherUpdate flag
282 EXPECT_FALSE(mEngine.needsAnotherUpdate());
283}
284
Lloyd Piquee82ed2d2019-11-13 19:28:12 -0800285TEST_F(CompositionTestPreComposition,
286 preCompositionSetsNeedsAnotherUpdateIfAtLeastOneLayerRequestsIt) {
Lloyd Piqueab039b52019-02-13 14:22:42 -0800287 EXPECT_CALL(*mLayer1FE, onPreComposition(_)).WillOnce(Return(true));
288 EXPECT_CALL(*mLayer2FE, onPreComposition(_)).WillOnce(Return(false));
289 EXPECT_CALL(*mLayer3FE, onPreComposition(_)).WillOnce(Return(false));
290
Lloyd Piquee82ed2d2019-11-13 19:28:12 -0800291 mRefreshArgs.outputs = {mOutput1};
292 mRefreshArgs.layers = {mLayer1, mLayer2, mLayer3, mLayer4};
293
Lloyd Piqueab039b52019-02-13 14:22:42 -0800294 mEngine.preComposition(mRefreshArgs);
295
296 EXPECT_TRUE(mEngine.needsAnotherUpdate());
297}
298
Lloyd Pique70d91362018-10-18 16:02:55 -0700299} // namespace
300} // namespace android::compositionengine