1 /*
2  * Copyright 2020 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 // TODO(b/129481165): remove the #pragma below and fix conversion issues
18 #pragma clang diagnostic push
19 #pragma clang diagnostic ignored "-Wconversion"
20 
21 #undef LOG_TAG
22 #define LOG_TAG "LibSurfaceFlingerUnittests"
23 
24 #include <gmock/gmock.h>
25 #include <gtest/gtest.h>
26 #include <gui/LayerMetadata.h>
27 
28 #include "BufferQueueLayer.h"
29 #include "BufferStateLayer.h"
30 #include "EffectLayer.h"
31 #include "Layer.h"
32 #include "TestableSurfaceFlinger.h"
33 #include "mock/DisplayHardware/MockComposer.h"
34 #include "mock/MockDispSync.h"
35 #include "mock/MockEventControlThread.h"
36 #include "mock/MockEventThread.h"
37 
38 namespace android {
39 
40 using testing::_;
41 using testing::DoAll;
42 using testing::Mock;
43 using testing::Return;
44 using testing::SetArgPointee;
45 
46 using android::Hwc2::IComposer;
47 using android::Hwc2::IComposerClient;
48 
49 using FakeHwcDisplayInjector = TestableSurfaceFlinger::FakeHwcDisplayInjector;
50 
51 /**
52  * This class covers all the test that are related to refresh rate selection.
53  */
54 class RefreshRateSelectionTest : public testing::Test {
55 public:
56     RefreshRateSelectionTest();
57     ~RefreshRateSelectionTest() override;
58 
59 protected:
60     static constexpr int DEFAULT_DISPLAY_WIDTH = 1920;
61     static constexpr int DEFAULT_DISPLAY_HEIGHT = 1024;
62     static constexpr uint32_t WIDTH = 100;
63     static constexpr uint32_t HEIGHT = 100;
64     static constexpr uint32_t LAYER_FLAGS = 0;
65     static constexpr int32_t PRIORITY_UNSET = -1;
66 
67     void setupScheduler();
68     void setupComposer(int virtualDisplayCount);
69     sp<BufferQueueLayer> createBufferQueueLayer();
70     sp<BufferStateLayer> createBufferStateLayer();
71     sp<EffectLayer> createEffectLayer();
72 
73     void setParent(Layer* child, Layer* parent);
74     void commitTransaction(Layer* layer);
75 
76     TestableSurfaceFlinger mFlinger;
77     Hwc2::mock::Composer* mComposer = nullptr;
78 
79     sp<Client> mClient;
80     sp<Layer> mParent;
81     sp<Layer> mChild;
82     sp<Layer> mGrandChild;
83 };
84 
RefreshRateSelectionTest()85 RefreshRateSelectionTest::RefreshRateSelectionTest() {
86     const ::testing::TestInfo* const test_info =
87             ::testing::UnitTest::GetInstance()->current_test_info();
88     ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
89 
90     setupScheduler();
91     setupComposer(0);
92 }
93 
~RefreshRateSelectionTest()94 RefreshRateSelectionTest::~RefreshRateSelectionTest() {
95     const ::testing::TestInfo* const test_info =
96             ::testing::UnitTest::GetInstance()->current_test_info();
97     ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
98 }
99 
createBufferQueueLayer()100 sp<BufferQueueLayer> RefreshRateSelectionTest::createBufferQueueLayer() {
101     sp<Client> client;
102     LayerCreationArgs args(mFlinger.flinger(), client, "buffer-queue-layer", WIDTH, HEIGHT,
103                            LAYER_FLAGS, LayerMetadata());
104     return new BufferQueueLayer(args);
105 }
106 
createBufferStateLayer()107 sp<BufferStateLayer> RefreshRateSelectionTest::createBufferStateLayer() {
108     sp<Client> client;
109     LayerCreationArgs args(mFlinger.flinger(), client, "buffer-queue-layer", WIDTH, HEIGHT,
110                            LAYER_FLAGS, LayerMetadata());
111     return new BufferStateLayer(args);
112 }
113 
createEffectLayer()114 sp<EffectLayer> RefreshRateSelectionTest::createEffectLayer() {
115     sp<Client> client;
116     LayerCreationArgs args(mFlinger.flinger(), client, "color-layer", WIDTH, HEIGHT, LAYER_FLAGS,
117                            LayerMetadata());
118     return new EffectLayer(args);
119 }
120 
setParent(Layer * child,Layer * parent)121 void RefreshRateSelectionTest::setParent(Layer* child, Layer* parent) {
122     child->setParent(parent);
123 }
124 
commitTransaction(Layer * layer)125 void RefreshRateSelectionTest::commitTransaction(Layer* layer) {
126     layer->commitTransaction(layer->getCurrentState());
127 }
128 
setupScheduler()129 void RefreshRateSelectionTest::setupScheduler() {
130     auto eventThread = std::make_unique<mock::EventThread>();
131     auto sfEventThread = std::make_unique<mock::EventThread>();
132 
133     EXPECT_CALL(*eventThread, registerDisplayEventConnection(_));
134     EXPECT_CALL(*eventThread, createEventConnection(_, _))
135             .WillOnce(Return(new EventThreadConnection(eventThread.get(), ResyncCallback(),
136                                                        ISurfaceComposer::eConfigChangedSuppress)));
137 
138     EXPECT_CALL(*sfEventThread, registerDisplayEventConnection(_));
139     EXPECT_CALL(*sfEventThread, createEventConnection(_, _))
140             .WillOnce(Return(new EventThreadConnection(sfEventThread.get(), ResyncCallback(),
141                                                        ISurfaceComposer::eConfigChangedSuppress)));
142 
143     auto primaryDispSync = std::make_unique<mock::DispSync>();
144 
145     EXPECT_CALL(*primaryDispSync, computeNextRefresh(0, _)).WillRepeatedly(Return(0));
146     EXPECT_CALL(*primaryDispSync, getPeriod())
147             .WillRepeatedly(Return(FakeHwcDisplayInjector::DEFAULT_REFRESH_RATE));
148     EXPECT_CALL(*primaryDispSync, expectedPresentTime(_)).WillRepeatedly(Return(0));
149     mFlinger.setupScheduler(std::move(primaryDispSync),
150                             std::make_unique<mock::EventControlThread>(), std::move(eventThread),
151                             std::move(sfEventThread));
152 }
153 
setupComposer(int virtualDisplayCount)154 void RefreshRateSelectionTest::setupComposer(int virtualDisplayCount) {
155     mComposer = new Hwc2::mock::Composer();
156     EXPECT_CALL(*mComposer, getMaxVirtualDisplayCount()).WillOnce(Return(virtualDisplayCount));
157     mFlinger.setupComposer(std::unique_ptr<Hwc2::Composer>(mComposer));
158 
159     Mock::VerifyAndClear(mComposer);
160 }
161 
162 namespace {
163 /* ------------------------------------------------------------------------
164  * Test cases
165  */
TEST_F(RefreshRateSelectionTest,testPriorityOnBufferQueueLayers)166 TEST_F(RefreshRateSelectionTest, testPriorityOnBufferQueueLayers) {
167     mParent = createBufferQueueLayer();
168     mChild = createBufferQueueLayer();
169     setParent(mChild.get(), mParent.get());
170     mGrandChild = createBufferQueueLayer();
171     setParent(mGrandChild.get(), mChild.get());
172 
173     ASSERT_EQ(PRIORITY_UNSET, mParent->getFrameRateSelectionPriority());
174     ASSERT_EQ(PRIORITY_UNSET, mChild->getFrameRateSelectionPriority());
175     ASSERT_EQ(PRIORITY_UNSET, mGrandChild->getFrameRateSelectionPriority());
176 
177     // Child has its own priority.
178     mGrandChild->setFrameRateSelectionPriority(1);
179     commitTransaction(mGrandChild.get());
180     ASSERT_EQ(PRIORITY_UNSET, mParent->getFrameRateSelectionPriority());
181     ASSERT_EQ(PRIORITY_UNSET, mChild->getFrameRateSelectionPriority());
182     ASSERT_EQ(1, mGrandChild->getFrameRateSelectionPriority());
183 
184     // Child inherits from his parent.
185     mChild->setFrameRateSelectionPriority(1);
186     commitTransaction(mChild.get());
187     mGrandChild->setFrameRateSelectionPriority(PRIORITY_UNSET);
188     commitTransaction(mGrandChild.get());
189 
190     ASSERT_EQ(PRIORITY_UNSET, mParent->getFrameRateSelectionPriority());
191     ASSERT_EQ(1, mChild->getFrameRateSelectionPriority());
192     ASSERT_EQ(1, mGrandChild->getFrameRateSelectionPriority());
193 
194     // Grandchild inherits from his grand parent.
195     mParent->setFrameRateSelectionPriority(1);
196     commitTransaction(mParent.get());
197     mChild->setFrameRateSelectionPriority(PRIORITY_UNSET);
198     commitTransaction(mChild.get());
199     mGrandChild->setFrameRateSelectionPriority(PRIORITY_UNSET);
200     commitTransaction(mGrandChild.get());
201     ASSERT_EQ(1, mParent->getFrameRateSelectionPriority());
202     ASSERT_EQ(1, mChild->getFrameRateSelectionPriority());
203     ASSERT_EQ(1, mGrandChild->getFrameRateSelectionPriority());
204 }
205 
TEST_F(RefreshRateSelectionTest,testPriorityOnBufferStateLayers)206 TEST_F(RefreshRateSelectionTest, testPriorityOnBufferStateLayers) {
207     mParent = createBufferStateLayer();
208     mChild = createBufferStateLayer();
209     setParent(mChild.get(), mParent.get());
210     mGrandChild = createBufferStateLayer();
211     setParent(mGrandChild.get(), mChild.get());
212 
213     ASSERT_EQ(PRIORITY_UNSET, mParent->getFrameRateSelectionPriority());
214     ASSERT_EQ(PRIORITY_UNSET, mChild->getFrameRateSelectionPriority());
215     ASSERT_EQ(PRIORITY_UNSET, mGrandChild->getFrameRateSelectionPriority());
216 
217     // Child has its own priority.
218     mGrandChild->setFrameRateSelectionPriority(1);
219     commitTransaction(mGrandChild.get());
220     ASSERT_EQ(PRIORITY_UNSET, mParent->getFrameRateSelectionPriority());
221     ASSERT_EQ(PRIORITY_UNSET, mChild->getFrameRateSelectionPriority());
222     ASSERT_EQ(1, mGrandChild->getFrameRateSelectionPriority());
223 
224     // Child inherits from his parent.
225     mChild->setFrameRateSelectionPriority(1);
226     commitTransaction(mChild.get());
227     mGrandChild->setFrameRateSelectionPriority(PRIORITY_UNSET);
228     commitTransaction(mGrandChild.get());
229     ASSERT_EQ(PRIORITY_UNSET, mParent->getFrameRateSelectionPriority());
230     ASSERT_EQ(1, mChild->getFrameRateSelectionPriority());
231     ASSERT_EQ(1, mGrandChild->getFrameRateSelectionPriority());
232 
233     // Grandchild inherits from his grand parent.
234     mParent->setFrameRateSelectionPriority(1);
235     commitTransaction(mParent.get());
236     mChild->setFrameRateSelectionPriority(PRIORITY_UNSET);
237     commitTransaction(mChild.get());
238     mGrandChild->setFrameRateSelectionPriority(PRIORITY_UNSET);
239     commitTransaction(mGrandChild.get());
240     ASSERT_EQ(1, mParent->getFrameRateSelectionPriority());
241     ASSERT_EQ(1, mChild->getFrameRateSelectionPriority());
242     ASSERT_EQ(1, mGrandChild->getFrameRateSelectionPriority());
243 }
244 
TEST_F(RefreshRateSelectionTest,testPriorityOnEffectLayers)245 TEST_F(RefreshRateSelectionTest, testPriorityOnEffectLayers) {
246     mParent = createEffectLayer();
247     mChild = createEffectLayer();
248     setParent(mChild.get(), mParent.get());
249     mGrandChild = createEffectLayer();
250     setParent(mGrandChild.get(), mChild.get());
251 
252     ASSERT_EQ(PRIORITY_UNSET, mParent->getFrameRateSelectionPriority());
253     ASSERT_EQ(PRIORITY_UNSET, mChild->getFrameRateSelectionPriority());
254     ASSERT_EQ(PRIORITY_UNSET, mGrandChild->getFrameRateSelectionPriority());
255 
256     // Child has its own priority.
257     mGrandChild->setFrameRateSelectionPriority(1);
258     commitTransaction(mGrandChild.get());
259     ASSERT_EQ(PRIORITY_UNSET, mParent->getFrameRateSelectionPriority());
260     ASSERT_EQ(PRIORITY_UNSET, mChild->getFrameRateSelectionPriority());
261     ASSERT_EQ(1, mGrandChild->getFrameRateSelectionPriority());
262 
263     // Child inherits from his parent.
264     mChild->setFrameRateSelectionPriority(1);
265     commitTransaction(mChild.get());
266     mGrandChild->setFrameRateSelectionPriority(PRIORITY_UNSET);
267     commitTransaction(mGrandChild.get());
268     ASSERT_EQ(PRIORITY_UNSET, mParent->getFrameRateSelectionPriority());
269     ASSERT_EQ(1, mChild->getFrameRateSelectionPriority());
270     ASSERT_EQ(1, mGrandChild->getFrameRateSelectionPriority());
271 
272     // Grandchild inherits from his grand parent.
273     mParent->setFrameRateSelectionPriority(1);
274     commitTransaction(mParent.get());
275     mChild->setFrameRateSelectionPriority(PRIORITY_UNSET);
276     commitTransaction(mChild.get());
277     mGrandChild->setFrameRateSelectionPriority(PRIORITY_UNSET);
278     commitTransaction(mGrandChild.get());
279     ASSERT_EQ(1, mParent->getFrameRateSelectionPriority());
280     ASSERT_EQ(1, mChild->getFrameRateSelectionPriority());
281     ASSERT_EQ(1, mGrandChild->getFrameRateSelectionPriority());
282 }
283 
284 } // namespace
285 } // namespace android
286 
287 // TODO(b/129481165): remove the #pragma below and fix conversion issues
288 #pragma clang diagnostic pop // ignored "-Wconversion"
289