blob: 353a5b0fe8774c87b6d3374b592eede48a8abebc [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 Pique70d91362018-10-18 16:02:55 -070018#include <compositionengine/impl/CompositionEngine.h>
Lloyd Piqueab039b52019-02-13 14:22:42 -080019#include <compositionengine/mock/Layer.h>
20#include <compositionengine/mock/LayerFE.h>
21#include <compositionengine/mock/Output.h>
Lloyd Pique70d91362018-10-18 16:02:55 -070022#include <gtest/gtest.h>
Lloyd Piqueb97e04f2018-10-18 17:07:05 -070023#include <renderengine/mock/RenderEngine.h>
Lloyd Pique70d91362018-10-18 16:02:55 -070024
Lloyd Pique441d5042018-10-18 16:49:51 -070025#include "MockHWComposer.h"
26
Lloyd Pique70d91362018-10-18 16:02:55 -070027namespace android::compositionengine {
28namespace {
29
Lloyd Piqueab039b52019-02-13 14:22:42 -080030using ::testing::_;
Lloyd Piquee82ed2d2019-11-13 19:28:12 -080031using ::testing::InSequence;
32using ::testing::Ref;
Lloyd Piqueab039b52019-02-13 14:22:42 -080033using ::testing::Return;
34using ::testing::SaveArg;
Lloyd Pique441d5042018-10-18 16:49:51 -070035using ::testing::StrictMock;
36
Lloyd Piquee82ed2d2019-11-13 19:28:12 -080037struct CompositionEngineTest : public testing::Test {
Lloyd Piqueab039b52019-02-13 14:22:42 -080038 android::mock::HWComposer* mHwc = new StrictMock<android::mock::HWComposer>();
Lloyd Piqueb97e04f2018-10-18 17:07:05 -070039 renderengine::mock::RenderEngine* mRenderEngine =
40 new StrictMock<renderengine::mock::RenderEngine>();
Lloyd Pique441d5042018-10-18 16:49:51 -070041 impl::CompositionEngine mEngine;
Lloyd Piquee82ed2d2019-11-13 19:28:12 -080042 CompositionRefreshArgs mRefreshArgs;
43
44 std::shared_ptr<mock::Output> mOutput1{std::make_shared<StrictMock<mock::Output>>()};
45 std::shared_ptr<mock::Output> mOutput2{std::make_shared<StrictMock<mock::Output>>()};
46 std::shared_ptr<mock::Output> mOutput3{std::make_shared<StrictMock<mock::Output>>()};
47
48 std::shared_ptr<mock::Layer> mLayer1{std::make_shared<StrictMock<mock::Layer>>()};
49 std::shared_ptr<mock::Layer> mLayer2{std::make_shared<StrictMock<mock::Layer>>()};
50 std::shared_ptr<mock::Layer> mLayer3{std::make_shared<StrictMock<mock::Layer>>()};
51 std::shared_ptr<mock::Layer> mLayer4{std::make_shared<StrictMock<mock::Layer>>()};
Lloyd Pique70d91362018-10-18 16:02:55 -070052};
53
Lloyd Pique70d91362018-10-18 16:02:55 -070054TEST_F(CompositionEngineTest, canInstantiateCompositionEngine) {
55 auto engine = impl::createCompositionEngine();
56 EXPECT_TRUE(engine.get() != nullptr);
57}
58
Lloyd Pique441d5042018-10-18 16:49:51 -070059TEST_F(CompositionEngineTest, canSetHWComposer) {
60 mEngine.setHwComposer(std::unique_ptr<android::HWComposer>(mHwc));
61
62 EXPECT_EQ(mHwc, &mEngine.getHwComposer());
63}
64
Lloyd Piqueb97e04f2018-10-18 17:07:05 -070065TEST_F(CompositionEngineTest, canSetRenderEngine) {
66 mEngine.setRenderEngine(std::unique_ptr<renderengine::RenderEngine>(mRenderEngine));
67
68 EXPECT_EQ(mRenderEngine, &mEngine.getRenderEngine());
69}
70
Lloyd Piqueab039b52019-02-13 14:22:42 -080071/*
Lloyd Piquee82ed2d2019-11-13 19:28:12 -080072 * CompositionEngine::present
73 */
74
75struct CompositionEnginePresentTest : public CompositionEngineTest {
76 struct CompositionEnginePartialMock : public impl::CompositionEngine {
77 // These are the overridable functions CompositionEngine::present() may
78 // call, and have separate test coverage.
79 MOCK_METHOD1(preComposition, void(CompositionRefreshArgs&));
80 };
81
82 StrictMock<CompositionEnginePartialMock> mEngine;
83};
84
85TEST_F(CompositionEnginePresentTest, worksWithEmptyRequest) {
86 // present() always calls preComposition()
87 EXPECT_CALL(mEngine, preComposition(Ref(mRefreshArgs)));
88
89 mEngine.present(mRefreshArgs);
90}
91
92TEST_F(CompositionEnginePresentTest, worksAsExpected) {
93 // Expect calls to in a certain sequence
94 InSequence seq;
95
96 // present() always calls preComposition()
97 EXPECT_CALL(mEngine, preComposition(Ref(mRefreshArgs)));
98
99 // The first step in presenting is to make sure all outputs are prepared.
100 EXPECT_CALL(*mOutput1, prepare(Ref(mRefreshArgs), _));
101 EXPECT_CALL(*mOutput2, prepare(Ref(mRefreshArgs), _));
102 EXPECT_CALL(*mOutput3, prepare(Ref(mRefreshArgs), _));
103
104 // The next step in presenting is to make sure all outputs have the latest
105 // state from the front-end (SurfaceFlinger).
106 EXPECT_CALL(*mOutput1, updateLayerStateFromFE(Ref(mRefreshArgs)));
107 EXPECT_CALL(*mOutput2, updateLayerStateFromFE(Ref(mRefreshArgs)));
108 EXPECT_CALL(*mOutput3, updateLayerStateFromFE(Ref(mRefreshArgs)));
109
110 // The last step is to actually present each output.
111 EXPECT_CALL(*mOutput1, present(Ref(mRefreshArgs)));
112 EXPECT_CALL(*mOutput2, present(Ref(mRefreshArgs)));
113 EXPECT_CALL(*mOutput3, present(Ref(mRefreshArgs)));
114
115 mRefreshArgs.outputs = {mOutput1, mOutput2, mOutput3};
116 mEngine.present(mRefreshArgs);
117}
118
119/*
Lloyd Piqueab039b52019-02-13 14:22:42 -0800120 * CompositionEngine::preComposition
121 */
122
Lloyd Piquee82ed2d2019-11-13 19:28:12 -0800123struct CompositionTestPreComposition : public CompositionEngineTest {
124 CompositionTestPreComposition() {
Lloyd Piqueab039b52019-02-13 14:22:42 -0800125 EXPECT_CALL(*mLayer1, getLayerFE()).WillRepeatedly(Return(mLayer1FE));
126 EXPECT_CALL(*mLayer2, getLayerFE()).WillRepeatedly(Return(mLayer2FE));
127 EXPECT_CALL(*mLayer3, getLayerFE()).WillRepeatedly(Return(mLayer3FE));
128 // getLayerFE() can return nullptr. Ensure that this is handled.
129 EXPECT_CALL(*mLayer4, getLayerFE()).WillRepeatedly(Return(nullptr));
Lloyd Piqueab039b52019-02-13 14:22:42 -0800130 }
131
Lloyd Piqueab039b52019-02-13 14:22:42 -0800132 sp<StrictMock<mock::LayerFE>> mLayer1FE{new StrictMock<mock::LayerFE>()};
133 sp<StrictMock<mock::LayerFE>> mLayer2FE{new StrictMock<mock::LayerFE>()};
134 sp<StrictMock<mock::LayerFE>> mLayer3FE{new StrictMock<mock::LayerFE>()};
Lloyd Piqueab039b52019-02-13 14:22:42 -0800135};
136
Lloyd Piquee82ed2d2019-11-13 19:28:12 -0800137TEST_F(CompositionTestPreComposition, preCompositionSetsFrameTimestamp) {
Lloyd Piqueab039b52019-02-13 14:22:42 -0800138 const nsecs_t before = systemTime(SYSTEM_TIME_MONOTONIC);
Lloyd Piquee82ed2d2019-11-13 19:28:12 -0800139 mEngine.preComposition(mRefreshArgs);
Lloyd Piqueab039b52019-02-13 14:22:42 -0800140 const nsecs_t after = systemTime(SYSTEM_TIME_MONOTONIC);
141
142 // The frame timestamp should be between the before and after timestamps
143 EXPECT_GE(mEngine.getLastFrameRefreshTimestamp(), before);
144 EXPECT_LE(mEngine.getLastFrameRefreshTimestamp(), after);
145}
146
Lloyd Piquee82ed2d2019-11-13 19:28:12 -0800147TEST_F(CompositionTestPreComposition, preCompositionInvokesLayerPreCompositionWithFrameTimestamp) {
Lloyd Piqueab039b52019-02-13 14:22:42 -0800148 nsecs_t ts1 = 0;
149 nsecs_t ts2 = 0;
150 nsecs_t ts3 = 0;
151 EXPECT_CALL(*mLayer1FE, onPreComposition(_)).WillOnce(DoAll(SaveArg<0>(&ts1), Return(false)));
152 EXPECT_CALL(*mLayer2FE, onPreComposition(_)).WillOnce(DoAll(SaveArg<0>(&ts2), Return(false)));
153 EXPECT_CALL(*mLayer3FE, onPreComposition(_)).WillOnce(DoAll(SaveArg<0>(&ts3), Return(false)));
154
Lloyd Piquee82ed2d2019-11-13 19:28:12 -0800155 mRefreshArgs.outputs = {mOutput1};
156 mRefreshArgs.layers = {mLayer1, mLayer2, mLayer3, mLayer4};
157
Lloyd Piqueab039b52019-02-13 14:22:42 -0800158 mEngine.preComposition(mRefreshArgs);
159
160 // Each of the onPreComposition calls should used the same refresh timestamp
161 EXPECT_EQ(ts1, mEngine.getLastFrameRefreshTimestamp());
162 EXPECT_EQ(ts2, mEngine.getLastFrameRefreshTimestamp());
163 EXPECT_EQ(ts3, mEngine.getLastFrameRefreshTimestamp());
164}
165
Lloyd Piquee82ed2d2019-11-13 19:28:12 -0800166TEST_F(CompositionTestPreComposition, preCompositionDefaultsToNoUpdateNeeded) {
Lloyd Piqueab039b52019-02-13 14:22:42 -0800167 EXPECT_CALL(*mLayer1FE, onPreComposition(_)).WillOnce(Return(false));
168 EXPECT_CALL(*mLayer2FE, onPreComposition(_)).WillOnce(Return(false));
169 EXPECT_CALL(*mLayer3FE, onPreComposition(_)).WillOnce(Return(false));
170
171 mEngine.setNeedsAnotherUpdateForTest(true);
172
Lloyd Piquee82ed2d2019-11-13 19:28:12 -0800173 mRefreshArgs.outputs = {mOutput1};
174 mRefreshArgs.layers = {mLayer1, mLayer2, mLayer3, mLayer4};
175
Lloyd Piqueab039b52019-02-13 14:22:42 -0800176 mEngine.preComposition(mRefreshArgs);
177
178 // The call should have cleared the needsAnotherUpdate flag
179 EXPECT_FALSE(mEngine.needsAnotherUpdate());
180}
181
Lloyd Piquee82ed2d2019-11-13 19:28:12 -0800182TEST_F(CompositionTestPreComposition,
183 preCompositionSetsNeedsAnotherUpdateIfAtLeastOneLayerRequestsIt) {
Lloyd Piqueab039b52019-02-13 14:22:42 -0800184 EXPECT_CALL(*mLayer1FE, onPreComposition(_)).WillOnce(Return(true));
185 EXPECT_CALL(*mLayer2FE, onPreComposition(_)).WillOnce(Return(false));
186 EXPECT_CALL(*mLayer3FE, onPreComposition(_)).WillOnce(Return(false));
187
Lloyd Piquee82ed2d2019-11-13 19:28:12 -0800188 mRefreshArgs.outputs = {mOutput1};
189 mRefreshArgs.layers = {mLayer1, mLayer2, mLayer3, mLayer4};
190
Lloyd Piqueab039b52019-02-13 14:22:42 -0800191 mEngine.preComposition(mRefreshArgs);
192
193 EXPECT_TRUE(mEngine.needsAnotherUpdate());
194}
195
Lloyd Pique70d91362018-10-18 16:02:55 -0700196} // namespace
197} // namespace android::compositionengine