1 /*
2 * Copyright 2019 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 "LayerHistoryTest"
23
24 #include <gmock/gmock.h>
25 #include <gtest/gtest.h>
26 #include <log/log.h>
27
28 #include "Scheduler/LayerHistory.h"
29 #include "Scheduler/LayerInfo.h"
30 #include "TestableScheduler.h"
31 #include "TestableSurfaceFlinger.h"
32 #include "mock/MockLayer.h"
33
34 using testing::_;
35 using testing::Return;
36
37 namespace android::scheduler {
38
39 class LayerHistoryTest : public testing::Test {
40 protected:
41 static constexpr auto PRESENT_TIME_HISTORY_SIZE = LayerInfo::PresentTimeHistory::HISTORY_SIZE;
42 static constexpr auto MAX_FREQUENT_LAYER_PERIOD_NS = LayerInfo::MAX_FREQUENT_LAYER_PERIOD_NS;
43
44 static constexpr float LO_FPS = 30.f;
45 static constexpr nsecs_t LO_FPS_PERIOD = 33'333'333;
46
47 static constexpr float HI_FPS = 90.f;
48 static constexpr nsecs_t HI_FPS_PERIOD = 11'111'111;
49
LayerHistoryTest()50 LayerHistoryTest() { mFlinger.resetScheduler(mScheduler); }
51
history()52 impl::LayerHistory& history() { return *mScheduler->mutableLayerHistory(); }
history() const53 const impl::LayerHistory& history() const { return *mScheduler->mutableLayerHistory(); }
54
layerCount() const55 size_t layerCount() const { return mScheduler->layerHistorySize(); }
activeLayerCount() const56 size_t activeLayerCount() const NO_THREAD_SAFETY_ANALYSIS { return history().mActiveLayersEnd; }
57
frequentLayerCount(nsecs_t now) const58 size_t frequentLayerCount(nsecs_t now) const NO_THREAD_SAFETY_ANALYSIS {
59 const auto& infos = history().mLayerInfos;
60 return std::count_if(infos.begin(), infos.begin() + history().mActiveLayersEnd,
61 [now](const auto& pair) { return pair.second->isFrequent(now); });
62 }
63
createLayer()64 auto createLayer() { return sp<mock::MockLayer>(new mock::MockLayer(mFlinger.flinger())); }
65
66 Hwc2::mock::Display mDisplay;
67 RefreshRateConfigs mConfigs{{HWC2::Display::Config::Builder(mDisplay, 0)
68 .setVsyncPeriod(int32_t(LO_FPS_PERIOD))
69 .setConfigGroup(0)
70 .build(),
71 HWC2::Display::Config::Builder(mDisplay, 1)
72 .setVsyncPeriod(int32_t(HI_FPS_PERIOD))
73 .setConfigGroup(0)
74 .build()},
75 HwcConfigIndexType(0)};
76 TestableScheduler* const mScheduler{new TestableScheduler(mConfigs, false)};
77 TestableSurfaceFlinger mFlinger;
78
79 const nsecs_t mTime = systemTime();
80 };
81
82 namespace {
83
TEST_F(LayerHistoryTest,oneLayer)84 TEST_F(LayerHistoryTest, oneLayer) {
85 const auto layer = createLayer();
86 EXPECT_CALL(*layer, isVisible()).WillRepeatedly(Return(true));
87 EXPECT_CALL(*layer, getFrameSelectionPriority()).WillRepeatedly(Return(1));
88 EXPECT_CALL(*layer, getFrameRateForLayerTree()).WillRepeatedly(Return(Layer::FrameRate()));
89
90 EXPECT_EQ(1, layerCount());
91 EXPECT_EQ(0, activeLayerCount());
92
93 // no layers are returned if no layers are active.
94 ASSERT_TRUE(history().summarize(mTime).empty());
95 EXPECT_EQ(0, activeLayerCount());
96
97 // no layers are returned if active layers have insufficient history.
98 for (int i = 0; i < PRESENT_TIME_HISTORY_SIZE - 1; i++) {
99 history().record(layer.get(), 0, mTime, LayerHistory::LayerUpdateType::Buffer);
100 ASSERT_TRUE(history().summarize(mTime).empty());
101 EXPECT_EQ(1, activeLayerCount());
102 }
103
104 // High FPS is returned once enough history has been recorded.
105 for (int i = 0; i < 10; i++) {
106 history().record(layer.get(), 0, mTime, LayerHistory::LayerUpdateType::Buffer);
107 ASSERT_EQ(1, history().summarize(mTime).size());
108 EXPECT_FLOAT_EQ(HI_FPS, history().summarize(mTime)[0].desiredRefreshRate);
109 EXPECT_EQ(1, activeLayerCount());
110 }
111 }
112
TEST_F(LayerHistoryTest,explicitTimestamp)113 TEST_F(LayerHistoryTest, explicitTimestamp) {
114 const auto layer = createLayer();
115 EXPECT_CALL(*layer, isVisible()).WillRepeatedly(Return(true));
116 EXPECT_CALL(*layer, getFrameSelectionPriority()).WillRepeatedly(Return(1));
117 EXPECT_CALL(*layer, getFrameRateForLayerTree()).WillRepeatedly(Return(Layer::FrameRate()));
118
119 EXPECT_EQ(1, layerCount());
120 EXPECT_EQ(0, activeLayerCount());
121
122 nsecs_t time = mTime;
123 for (int i = 0; i < PRESENT_TIME_HISTORY_SIZE; i++) {
124 history().record(layer.get(), time, time, LayerHistory::LayerUpdateType::Buffer);
125 time += LO_FPS_PERIOD;
126 }
127
128 ASSERT_EQ(1, history().summarize(mTime).size());
129 EXPECT_FLOAT_EQ(LO_FPS, history().summarize(mTime)[0].desiredRefreshRate);
130 EXPECT_EQ(1, activeLayerCount());
131 EXPECT_EQ(1, frequentLayerCount(time));
132 }
133
TEST_F(LayerHistoryTest,multipleLayers)134 TEST_F(LayerHistoryTest, multipleLayers) {
135 auto layer1 = createLayer();
136 auto layer2 = createLayer();
137 auto layer3 = createLayer();
138
139 EXPECT_CALL(*layer1, isVisible()).WillRepeatedly(Return(true));
140 EXPECT_CALL(*layer1, getFrameSelectionPriority()).WillRepeatedly(Return(1));
141 EXPECT_CALL(*layer1, getFrameRateForLayerTree()).WillRepeatedly(Return(Layer::FrameRate()));
142
143 EXPECT_CALL(*layer2, isVisible()).WillRepeatedly(Return(true));
144 EXPECT_CALL(*layer2, getFrameSelectionPriority()).WillRepeatedly(Return(1));
145 EXPECT_CALL(*layer2, getFrameRateForLayerTree()).WillRepeatedly(Return(Layer::FrameRate()));
146
147 EXPECT_CALL(*layer3, isVisible()).WillRepeatedly(Return(true));
148 EXPECT_CALL(*layer3, getFrameSelectionPriority()).WillRepeatedly(Return(1));
149 EXPECT_CALL(*layer3, getFrameRateForLayerTree()).WillRepeatedly(Return(Layer::FrameRate()));
150 nsecs_t time = mTime;
151
152 EXPECT_EQ(3, layerCount());
153 EXPECT_EQ(0, activeLayerCount());
154 EXPECT_EQ(0, frequentLayerCount(time));
155
156 // layer1 is active but infrequent.
157 for (int i = 0; i < PRESENT_TIME_HISTORY_SIZE; i++) {
158 history().record(layer1.get(), time, time, LayerHistory::LayerUpdateType::Buffer);
159 time += MAX_FREQUENT_LAYER_PERIOD_NS.count();
160 }
161
162 ASSERT_EQ(1, history().summarize(time).size());
163 EXPECT_FLOAT_EQ(LO_FPS, history().summarize(time)[0].desiredRefreshRate);
164 EXPECT_EQ(1, activeLayerCount());
165 EXPECT_EQ(0, frequentLayerCount(time));
166
167 // layer2 is frequent and has high refresh rate.
168 for (int i = 0; i < PRESENT_TIME_HISTORY_SIZE; i++) {
169 history().record(layer2.get(), time, time, LayerHistory::LayerUpdateType::Buffer);
170 time += HI_FPS_PERIOD;
171 }
172
173 // layer1 is still active but infrequent.
174 history().record(layer1.get(), time, time, LayerHistory::LayerUpdateType::Buffer);
175
176 ASSERT_EQ(2, history().summarize(time).size());
177 EXPECT_FLOAT_EQ(LO_FPS, history().summarize(time)[0].desiredRefreshRate);
178 EXPECT_FLOAT_EQ(HI_FPS, history().summarize(time)[1].desiredRefreshRate);
179 EXPECT_EQ(2, activeLayerCount());
180 EXPECT_EQ(1, frequentLayerCount(time));
181
182 // layer1 is no longer active.
183 // layer2 is frequent and has low refresh rate.
184 for (int i = 0; i < PRESENT_TIME_HISTORY_SIZE; i++) {
185 history().record(layer2.get(), time, time, LayerHistory::LayerUpdateType::Buffer);
186 time += LO_FPS_PERIOD;
187 }
188
189 ASSERT_EQ(1, history().summarize(time).size());
190 EXPECT_FLOAT_EQ(LO_FPS, history().summarize(time)[0].desiredRefreshRate);
191 EXPECT_EQ(1, activeLayerCount());
192 EXPECT_EQ(1, frequentLayerCount(time));
193
194 // layer2 still has low refresh rate.
195 // layer3 has high refresh rate but not enough history.
196 constexpr int RATIO = LO_FPS_PERIOD / HI_FPS_PERIOD;
197 for (int i = 0; i < PRESENT_TIME_HISTORY_SIZE - 1; i++) {
198 if (i % RATIO == 0) {
199 history().record(layer2.get(), time, time, LayerHistory::LayerUpdateType::Buffer);
200 }
201
202 history().record(layer3.get(), time, time, LayerHistory::LayerUpdateType::Buffer);
203 time += HI_FPS_PERIOD;
204 }
205
206 ASSERT_EQ(1, history().summarize(time).size());
207 EXPECT_FLOAT_EQ(LO_FPS, history().summarize(time)[0].desiredRefreshRate);
208 EXPECT_EQ(2, activeLayerCount());
209 EXPECT_EQ(2, frequentLayerCount(time));
210
211 // layer3 becomes recently active.
212 history().record(layer3.get(), time, time, LayerHistory::LayerUpdateType::Buffer);
213 ASSERT_EQ(2, history().summarize(time).size());
214 EXPECT_FLOAT_EQ(LO_FPS, history().summarize(time)[0].desiredRefreshRate);
215 EXPECT_FLOAT_EQ(HI_FPS, history().summarize(time)[1].desiredRefreshRate);
216 EXPECT_EQ(2, activeLayerCount());
217 EXPECT_EQ(2, frequentLayerCount(time));
218
219 // layer1 expires.
220 layer1.clear();
221 ASSERT_EQ(2, history().summarize(time).size());
222 EXPECT_FLOAT_EQ(LO_FPS, history().summarize(time)[0].desiredRefreshRate);
223 EXPECT_FLOAT_EQ(HI_FPS, history().summarize(time)[1].desiredRefreshRate);
224 EXPECT_EQ(2, layerCount());
225 EXPECT_EQ(2, activeLayerCount());
226 EXPECT_EQ(2, frequentLayerCount(time));
227
228 // layer2 still has low refresh rate.
229 // layer3 becomes inactive.
230 for (int i = 0; i < PRESENT_TIME_HISTORY_SIZE; i++) {
231 history().record(layer2.get(), time, time, LayerHistory::LayerUpdateType::Buffer);
232 time += LO_FPS_PERIOD;
233 }
234
235 ASSERT_EQ(1, history().summarize(time).size());
236 EXPECT_FLOAT_EQ(LO_FPS, history().summarize(time)[0].desiredRefreshRate);
237 EXPECT_EQ(1, activeLayerCount());
238 EXPECT_EQ(1, frequentLayerCount(time));
239
240 // layer2 expires.
241 layer2.clear();
242 ASSERT_TRUE(history().summarize(time).empty());
243 EXPECT_EQ(1, layerCount());
244 EXPECT_EQ(0, activeLayerCount());
245 EXPECT_EQ(0, frequentLayerCount(time));
246
247 // layer3 becomes active and has high refresh rate.
248 for (int i = 0; i < PRESENT_TIME_HISTORY_SIZE; i++) {
249 history().record(layer3.get(), time, time, LayerHistory::LayerUpdateType::Buffer);
250 time += HI_FPS_PERIOD;
251 }
252
253 ASSERT_EQ(1, history().summarize(time).size());
254 EXPECT_FLOAT_EQ(HI_FPS, history().summarize(time)[0].desiredRefreshRate);
255 EXPECT_EQ(1, layerCount());
256 EXPECT_EQ(1, activeLayerCount());
257 EXPECT_EQ(1, frequentLayerCount(time));
258
259 // layer3 expires.
260 layer3.clear();
261 ASSERT_TRUE(history().summarize(time).empty());
262 EXPECT_EQ(0, layerCount());
263 EXPECT_EQ(0, activeLayerCount());
264 EXPECT_EQ(0, frequentLayerCount(time));
265 }
266
267 } // namespace
268 } // namespace android::scheduler
269
270 // TODO(b/129481165): remove the #pragma below and fix conversion issues
271 #pragma clang diagnostic pop // ignored "-Wconversion"
272