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