blob: 49e7c7044a9ba4c60eedacef13e04d74eab2b4d0 [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"
28
Lloyd Pique70d91362018-10-18 16:02:55 -070029namespace android::compositionengine {
30namespace {
31
Lloyd Piqueab039b52019-02-13 14:22:42 -080032using ::testing::_;
Lloyd Piquee82ed2d2019-11-13 19:28:12 -080033using ::testing::InSequence;
34using ::testing::Ref;
Lloyd Piqueab039b52019-02-13 14:22:42 -080035using ::testing::Return;
Lloyd Piqueaed56ab2019-11-13 22:34:11 -080036using ::testing::ReturnRef;
Lloyd Piqueab039b52019-02-13 14:22:42 -080037using ::testing::SaveArg;
Lloyd Pique441d5042018-10-18 16:49:51 -070038using ::testing::StrictMock;
39
Lloyd Piquee82ed2d2019-11-13 19:28:12 -080040struct CompositionEngineTest : public testing::Test {
Lloyd Piqueab039b52019-02-13 14:22:42 -080041 android::mock::HWComposer* mHwc = new StrictMock<android::mock::HWComposer>();
Lloyd Piqueb97e04f2018-10-18 17:07:05 -070042 renderengine::mock::RenderEngine* mRenderEngine =
43 new StrictMock<renderengine::mock::RenderEngine>();
Lloyd Pique441d5042018-10-18 16:49:51 -070044 impl::CompositionEngine mEngine;
Lloyd Piquee82ed2d2019-11-13 19:28:12 -080045 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 std::shared_ptr<mock::Layer> mLayer1{std::make_shared<StrictMock<mock::Layer>>()};
52 std::shared_ptr<mock::Layer> mLayer2{std::make_shared<StrictMock<mock::Layer>>()};
53 std::shared_ptr<mock::Layer> mLayer3{std::make_shared<StrictMock<mock::Layer>>()};
54 std::shared_ptr<mock::Layer> mLayer4{std::make_shared<StrictMock<mock::Layer>>()};
Lloyd Pique70d91362018-10-18 16:02:55 -070055};
56
Lloyd Pique70d91362018-10-18 16:02:55 -070057TEST_F(CompositionEngineTest, canInstantiateCompositionEngine) {
58 auto engine = impl::createCompositionEngine();
59 EXPECT_TRUE(engine.get() != nullptr);
60}
61
Lloyd Pique441d5042018-10-18 16:49:51 -070062TEST_F(CompositionEngineTest, canSetHWComposer) {
63 mEngine.setHwComposer(std::unique_ptr<android::HWComposer>(mHwc));
64
65 EXPECT_EQ(mHwc, &mEngine.getHwComposer());
66}
67
Lloyd Piqueb97e04f2018-10-18 17:07:05 -070068TEST_F(CompositionEngineTest, canSetRenderEngine) {
69 mEngine.setRenderEngine(std::unique_ptr<renderengine::RenderEngine>(mRenderEngine));
70
71 EXPECT_EQ(mRenderEngine, &mEngine.getRenderEngine());
72}
73
Lloyd Piqueab039b52019-02-13 14:22:42 -080074/*
Lloyd Piquee82ed2d2019-11-13 19:28:12 -080075 * CompositionEngine::present
76 */
77
78struct CompositionEnginePresentTest : public CompositionEngineTest {
79 struct CompositionEnginePartialMock : public impl::CompositionEngine {
80 // These are the overridable functions CompositionEngine::present() may
81 // call, and have separate test coverage.
82 MOCK_METHOD1(preComposition, void(CompositionRefreshArgs&));
83 };
84
85 StrictMock<CompositionEnginePartialMock> mEngine;
86};
87
88TEST_F(CompositionEnginePresentTest, worksWithEmptyRequest) {
89 // present() always calls preComposition()
90 EXPECT_CALL(mEngine, preComposition(Ref(mRefreshArgs)));
91
92 mEngine.present(mRefreshArgs);
93}
94
95TEST_F(CompositionEnginePresentTest, worksAsExpected) {
96 // Expect calls to in a certain sequence
97 InSequence seq;
98
99 // present() always calls preComposition()
100 EXPECT_CALL(mEngine, preComposition(Ref(mRefreshArgs)));
101
102 // The first step in presenting is to make sure all outputs are prepared.
103 EXPECT_CALL(*mOutput1, prepare(Ref(mRefreshArgs), _));
104 EXPECT_CALL(*mOutput2, prepare(Ref(mRefreshArgs), _));
105 EXPECT_CALL(*mOutput3, prepare(Ref(mRefreshArgs), _));
106
107 // The next step in presenting is to make sure all outputs have the latest
108 // state from the front-end (SurfaceFlinger).
109 EXPECT_CALL(*mOutput1, updateLayerStateFromFE(Ref(mRefreshArgs)));
110 EXPECT_CALL(*mOutput2, updateLayerStateFromFE(Ref(mRefreshArgs)));
111 EXPECT_CALL(*mOutput3, updateLayerStateFromFE(Ref(mRefreshArgs)));
112
113 // The last step is to actually present each output.
114 EXPECT_CALL(*mOutput1, present(Ref(mRefreshArgs)));
115 EXPECT_CALL(*mOutput2, present(Ref(mRefreshArgs)));
116 EXPECT_CALL(*mOutput3, present(Ref(mRefreshArgs)));
117
118 mRefreshArgs.outputs = {mOutput1, mOutput2, mOutput3};
119 mEngine.present(mRefreshArgs);
120}
121
122/*
Lloyd Piqueaed56ab2019-11-13 22:34:11 -0800123 * CompositionEngine::updateCursorAsync
124 */
125
126struct CompositionEngineUpdateCursorAsyncTest : public CompositionEngineTest {
127public:
128 CompositionEngineUpdateCursorAsyncTest() {
129 EXPECT_CALL(*mOutput1, getOutputLayerCount()).WillRepeatedly(Return(0));
130 EXPECT_CALL(*mOutput1, getOutputLayerOrderedByZByIndex(_)).Times(0);
131
132 EXPECT_CALL(*mOutput2, getOutputLayerCount()).WillRepeatedly(Return(1));
133 EXPECT_CALL(*mOutput2, getOutputLayerOrderedByZByIndex(0))
134 .WillRepeatedly(Return(&mOutput2OutputLayer1));
135
136 EXPECT_CALL(*mOutput3, getOutputLayerCount()).WillRepeatedly(Return(2));
137 EXPECT_CALL(*mOutput3, getOutputLayerOrderedByZByIndex(0))
138 .WillRepeatedly(Return(&mOutput3OutputLayer1));
139 EXPECT_CALL(*mOutput3, getOutputLayerOrderedByZByIndex(1))
140 .WillRepeatedly(Return(&mOutput3OutputLayer2));
141
142 EXPECT_CALL(mOutput2OutputLayer1, getLayerFE()).WillRepeatedly(ReturnRef(mOutput2Layer1FE));
143 EXPECT_CALL(mOutput3OutputLayer1, getLayerFE()).WillRepeatedly(ReturnRef(mOutput3Layer1FE));
144 EXPECT_CALL(mOutput3OutputLayer2, getLayerFE()).WillRepeatedly(ReturnRef(mOutput3Layer2FE));
145
146 EXPECT_CALL(mOutput2OutputLayer1, getLayer()).WillRepeatedly(ReturnRef(mOutput2Layer1));
147 EXPECT_CALL(mOutput3OutputLayer1, getLayer()).WillRepeatedly(ReturnRef(mOutput3Layer1));
148 EXPECT_CALL(mOutput3OutputLayer2, getLayer()).WillRepeatedly(ReturnRef(mOutput3Layer2));
149
150 EXPECT_CALL(mOutput2Layer1, editFEState()).WillRepeatedly(ReturnRef(mOutput2Layer1FEState));
151 EXPECT_CALL(mOutput3Layer1, editFEState()).WillRepeatedly(ReturnRef(mOutput3Layer1FEState));
152 EXPECT_CALL(mOutput3Layer2, editFEState()).WillRepeatedly(ReturnRef(mOutput3Layer2FEState));
153 }
154
155 StrictMock<mock::OutputLayer> mOutput2OutputLayer1;
156 StrictMock<mock::OutputLayer> mOutput3OutputLayer1;
157 StrictMock<mock::OutputLayer> mOutput3OutputLayer2;
158
159 StrictMock<mock::LayerFE> mOutput2Layer1FE;
160 StrictMock<mock::LayerFE> mOutput3Layer1FE;
161 StrictMock<mock::LayerFE> mOutput3Layer2FE;
162
163 StrictMock<mock::Layer> mOutput2Layer1;
164 StrictMock<mock::Layer> mOutput3Layer1;
165 StrictMock<mock::Layer> mOutput3Layer2;
166
167 LayerFECompositionState mOutput2Layer1FEState;
168 LayerFECompositionState mOutput3Layer1FEState;
169 LayerFECompositionState mOutput3Layer2FEState;
170};
171
172TEST_F(CompositionEngineUpdateCursorAsyncTest, handlesNoOutputs) {
173 mEngine.updateCursorAsync(mRefreshArgs);
174}
175
176TEST_F(CompositionEngineUpdateCursorAsyncTest, handlesNoLayersBeingCursorLayers) {
177 EXPECT_CALL(mOutput2OutputLayer1, isHardwareCursor()).WillRepeatedly(Return(false));
178 EXPECT_CALL(mOutput3OutputLayer1, isHardwareCursor()).WillRepeatedly(Return(false));
179 EXPECT_CALL(mOutput3OutputLayer2, isHardwareCursor()).WillRepeatedly(Return(false));
180
181 mRefreshArgs.outputs = {mOutput1, mOutput2, mOutput3};
182
183 mEngine.updateCursorAsync(mRefreshArgs);
184}
185
186TEST_F(CompositionEngineUpdateCursorAsyncTest, handlesMultipleLayersBeingCursorLayers) {
187 {
188 InSequence seq;
189 EXPECT_CALL(mOutput2OutputLayer1, isHardwareCursor()).WillRepeatedly(Return(true));
190 EXPECT_CALL(mOutput2Layer1FE, latchCursorCompositionState(Ref(mOutput2Layer1FEState)));
191 EXPECT_CALL(mOutput2OutputLayer1, writeCursorPositionToHWC());
192 }
193
194 {
195 InSequence seq;
196 EXPECT_CALL(mOutput3OutputLayer1, isHardwareCursor()).WillRepeatedly(Return(true));
197 EXPECT_CALL(mOutput3Layer1FE, latchCursorCompositionState(Ref(mOutput3Layer1FEState)));
198 EXPECT_CALL(mOutput3OutputLayer1, writeCursorPositionToHWC());
199 }
200
201 {
202 InSequence seq;
203 EXPECT_CALL(mOutput3OutputLayer2, isHardwareCursor()).WillRepeatedly(Return(true));
204 EXPECT_CALL(mOutput3Layer2FE, latchCursorCompositionState(Ref(mOutput3Layer2FEState)));
205 EXPECT_CALL(mOutput3OutputLayer2, writeCursorPositionToHWC());
206 }
207
208 mRefreshArgs.outputs = {mOutput1, mOutput2, mOutput3};
209
210 mEngine.updateCursorAsync(mRefreshArgs);
211}
212
213/*
Lloyd Piqueab039b52019-02-13 14:22:42 -0800214 * CompositionEngine::preComposition
215 */
216
Lloyd Piquee82ed2d2019-11-13 19:28:12 -0800217struct CompositionTestPreComposition : public CompositionEngineTest {
218 CompositionTestPreComposition() {
Lloyd Piqueab039b52019-02-13 14:22:42 -0800219 EXPECT_CALL(*mLayer1, getLayerFE()).WillRepeatedly(Return(mLayer1FE));
220 EXPECT_CALL(*mLayer2, getLayerFE()).WillRepeatedly(Return(mLayer2FE));
221 EXPECT_CALL(*mLayer3, getLayerFE()).WillRepeatedly(Return(mLayer3FE));
222 // getLayerFE() can return nullptr. Ensure that this is handled.
223 EXPECT_CALL(*mLayer4, getLayerFE()).WillRepeatedly(Return(nullptr));
Lloyd Piqueab039b52019-02-13 14:22:42 -0800224 }
225
Lloyd Piqueab039b52019-02-13 14:22:42 -0800226 sp<StrictMock<mock::LayerFE>> mLayer1FE{new StrictMock<mock::LayerFE>()};
227 sp<StrictMock<mock::LayerFE>> mLayer2FE{new StrictMock<mock::LayerFE>()};
228 sp<StrictMock<mock::LayerFE>> mLayer3FE{new StrictMock<mock::LayerFE>()};
Lloyd Piqueab039b52019-02-13 14:22:42 -0800229};
230
Lloyd Piquee82ed2d2019-11-13 19:28:12 -0800231TEST_F(CompositionTestPreComposition, preCompositionSetsFrameTimestamp) {
Lloyd Piqueab039b52019-02-13 14:22:42 -0800232 const nsecs_t before = systemTime(SYSTEM_TIME_MONOTONIC);
Lloyd Piquee82ed2d2019-11-13 19:28:12 -0800233 mEngine.preComposition(mRefreshArgs);
Lloyd Piqueab039b52019-02-13 14:22:42 -0800234 const nsecs_t after = systemTime(SYSTEM_TIME_MONOTONIC);
235
236 // The frame timestamp should be between the before and after timestamps
237 EXPECT_GE(mEngine.getLastFrameRefreshTimestamp(), before);
238 EXPECT_LE(mEngine.getLastFrameRefreshTimestamp(), after);
239}
240
Lloyd Piquee82ed2d2019-11-13 19:28:12 -0800241TEST_F(CompositionTestPreComposition, preCompositionInvokesLayerPreCompositionWithFrameTimestamp) {
Lloyd Piqueab039b52019-02-13 14:22:42 -0800242 nsecs_t ts1 = 0;
243 nsecs_t ts2 = 0;
244 nsecs_t ts3 = 0;
245 EXPECT_CALL(*mLayer1FE, onPreComposition(_)).WillOnce(DoAll(SaveArg<0>(&ts1), Return(false)));
246 EXPECT_CALL(*mLayer2FE, onPreComposition(_)).WillOnce(DoAll(SaveArg<0>(&ts2), Return(false)));
247 EXPECT_CALL(*mLayer3FE, onPreComposition(_)).WillOnce(DoAll(SaveArg<0>(&ts3), Return(false)));
248
Lloyd Piquee82ed2d2019-11-13 19:28:12 -0800249 mRefreshArgs.outputs = {mOutput1};
250 mRefreshArgs.layers = {mLayer1, mLayer2, mLayer3, mLayer4};
251
Lloyd Piqueab039b52019-02-13 14:22:42 -0800252 mEngine.preComposition(mRefreshArgs);
253
254 // Each of the onPreComposition calls should used the same refresh timestamp
255 EXPECT_EQ(ts1, mEngine.getLastFrameRefreshTimestamp());
256 EXPECT_EQ(ts2, mEngine.getLastFrameRefreshTimestamp());
257 EXPECT_EQ(ts3, mEngine.getLastFrameRefreshTimestamp());
258}
259
Lloyd Piquee82ed2d2019-11-13 19:28:12 -0800260TEST_F(CompositionTestPreComposition, preCompositionDefaultsToNoUpdateNeeded) {
Lloyd Piqueab039b52019-02-13 14:22:42 -0800261 EXPECT_CALL(*mLayer1FE, onPreComposition(_)).WillOnce(Return(false));
262 EXPECT_CALL(*mLayer2FE, onPreComposition(_)).WillOnce(Return(false));
263 EXPECT_CALL(*mLayer3FE, onPreComposition(_)).WillOnce(Return(false));
264
265 mEngine.setNeedsAnotherUpdateForTest(true);
266
Lloyd Piquee82ed2d2019-11-13 19:28:12 -0800267 mRefreshArgs.outputs = {mOutput1};
268 mRefreshArgs.layers = {mLayer1, mLayer2, mLayer3, mLayer4};
269
Lloyd Piqueab039b52019-02-13 14:22:42 -0800270 mEngine.preComposition(mRefreshArgs);
271
272 // The call should have cleared the needsAnotherUpdate flag
273 EXPECT_FALSE(mEngine.needsAnotherUpdate());
274}
275
Lloyd Piquee82ed2d2019-11-13 19:28:12 -0800276TEST_F(CompositionTestPreComposition,
277 preCompositionSetsNeedsAnotherUpdateIfAtLeastOneLayerRequestsIt) {
Lloyd Piqueab039b52019-02-13 14:22:42 -0800278 EXPECT_CALL(*mLayer1FE, onPreComposition(_)).WillOnce(Return(true));
279 EXPECT_CALL(*mLayer2FE, onPreComposition(_)).WillOnce(Return(false));
280 EXPECT_CALL(*mLayer3FE, onPreComposition(_)).WillOnce(Return(false));
281
Lloyd Piquee82ed2d2019-11-13 19:28:12 -0800282 mRefreshArgs.outputs = {mOutput1};
283 mRefreshArgs.layers = {mLayer1, mLayer2, mLayer3, mLayer4};
284
Lloyd Piqueab039b52019-02-13 14:22:42 -0800285 mEngine.preComposition(mRefreshArgs);
286
287 EXPECT_TRUE(mEngine.needsAnotherUpdate());
288}
289
Lloyd Pique70d91362018-10-18 16:02:55 -0700290} // namespace
291} // namespace android::compositionengine