• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <binder/Binder.h>
18 #include <gmock/gmock.h>
19 #include <gtest/gtest.h>
20 
21 #include "Scheduler/VsyncModulator.h"
22 
23 namespace android::scheduler {
24 
25 class TestableVsyncModulator : public VsyncModulator {
26 public:
TestableVsyncModulator(const VsyncConfigSet & config,Now now)27     TestableVsyncModulator(const VsyncConfigSet& config, Now now) : VsyncModulator(config, now) {}
28 
binderDied(const wp<IBinder> & token)29     void binderDied(const wp<IBinder>& token) { VsyncModulator::binderDied(token); }
30 };
31 
32 class VsyncModulatorTest : public testing::Test {
33     enum {
34         SF_OFFSET_LATE,
35         APP_OFFSET_LATE,
36         SF_DURATION_LATE,
37         APP_DURATION_LATE,
38         SF_OFFSET_EARLY,
39         APP_OFFSET_EARLY,
40         SF_DURATION_EARLY,
41         APP_DURATION_EARLY,
42         SF_OFFSET_EARLY_GPU,
43         APP_OFFSET_EARLY_GPU,
44         SF_DURATION_EARLY_GPU,
45         APP_DURATION_EARLY_GPU,
46         HWC_MIN_WORK_DURATION,
47     };
48 
Now()49     static VsyncModulator::TimePoint Now() {
50         static VsyncModulator::TimePoint now;
51         return now += VsyncModulator::MIN_EARLY_TRANSACTION_TIME;
52     }
53 
54 protected:
55     static constexpr auto MIN_EARLY_TRANSACTION_FRAMES =
56             VsyncModulator::MIN_EARLY_TRANSACTION_FRAMES;
57 
58     using Schedule = scheduler::TransactionSchedule;
59     using nanos = std::chrono::nanoseconds;
60     const VsyncConfig kEarly{SF_OFFSET_EARLY, APP_OFFSET_EARLY, nanos(SF_DURATION_LATE),
61                              nanos(APP_DURATION_LATE)};
62     const VsyncConfig kEarlyGpu{SF_OFFSET_EARLY_GPU, APP_OFFSET_EARLY_GPU, nanos(SF_DURATION_EARLY),
63                                 nanos(APP_DURATION_EARLY)};
64     const VsyncConfig kLate{SF_OFFSET_LATE, APP_OFFSET_LATE, nanos(SF_DURATION_EARLY_GPU),
65                             nanos(APP_DURATION_EARLY_GPU)};
66 
67     const VsyncConfigSet mOffsets = {kEarly, kEarlyGpu, kLate, nanos(HWC_MIN_WORK_DURATION)};
68     sp<TestableVsyncModulator> mVsyncModulator = sp<TestableVsyncModulator>::make(mOffsets, Now);
69 
SetUp()70     void SetUp() override { EXPECT_EQ(kLate, mVsyncModulator->setVsyncConfigSet(mOffsets)); }
71 };
72 
73 #define CHECK_COMMIT(result, configs)                          \
74     EXPECT_EQ(result, mVsyncModulator->onTransactionCommit()); \
75     EXPECT_EQ(configs, mVsyncModulator->getVsyncConfig());
76 
77 #define CHECK_REFRESH(N, result, configs)                            \
78     for (int i = 0; i < N; i++) {                                    \
79         EXPECT_EQ(result, mVsyncModulator->onDisplayRefresh(false)); \
80         EXPECT_EQ(configs, mVsyncModulator->getVsyncConfig());       \
81     }
82 
TEST_F(VsyncModulatorTest,Late)83 TEST_F(VsyncModulatorTest, Late) {
84     EXPECT_FALSE(mVsyncModulator->setTransactionSchedule(Schedule::Late));
85 
86     CHECK_COMMIT(std::nullopt, kLate);
87     CHECK_REFRESH(MIN_EARLY_TRANSACTION_FRAMES, std::nullopt, kLate);
88 }
89 
TEST_F(VsyncModulatorTest,EarlyEnd)90 TEST_F(VsyncModulatorTest, EarlyEnd) {
91     const auto token = sp<BBinder>::make();
92     EXPECT_EQ(kEarly, mVsyncModulator->setTransactionSchedule(Schedule::EarlyEnd, token));
93 
94     CHECK_COMMIT(kEarly, kEarly);
95     CHECK_REFRESH(MIN_EARLY_TRANSACTION_FRAMES - 1, kEarly, kEarly);
96     CHECK_REFRESH(1, kLate, kLate);
97 }
98 
TEST_F(VsyncModulatorTest,EarlyStart)99 TEST_F(VsyncModulatorTest, EarlyStart) {
100     const auto token = sp<BBinder>::make();
101     EXPECT_EQ(kEarly, mVsyncModulator->setTransactionSchedule(Schedule::EarlyStart, token));
102 
103     CHECK_COMMIT(kEarly, kEarly);
104     CHECK_REFRESH(5 * MIN_EARLY_TRANSACTION_FRAMES, std::nullopt, kEarly);
105 
106     EXPECT_EQ(kEarly, mVsyncModulator->setTransactionSchedule(Schedule::EarlyEnd, token));
107 
108     CHECK_COMMIT(kEarly, kEarly);
109     CHECK_REFRESH(MIN_EARLY_TRANSACTION_FRAMES - 1, kEarly, kEarly);
110     CHECK_REFRESH(1, kLate, kLate);
111 }
112 
TEST_F(VsyncModulatorTest,EarlyStartWithMoreTransactions)113 TEST_F(VsyncModulatorTest, EarlyStartWithMoreTransactions) {
114     const auto token = sp<BBinder>::make();
115     EXPECT_EQ(kEarly, mVsyncModulator->setTransactionSchedule(Schedule::EarlyStart, token));
116 
117     CHECK_COMMIT(kEarly, kEarly);
118 
119     for (int i = 0; i < 5 * MIN_EARLY_TRANSACTION_FRAMES; i++) {
120         EXPECT_FALSE(mVsyncModulator->setTransactionSchedule(Schedule::Late));
121         CHECK_REFRESH(1, std::nullopt, kEarly);
122     }
123 
124     EXPECT_EQ(kEarly, mVsyncModulator->setTransactionSchedule(Schedule::EarlyEnd, token));
125 
126     CHECK_COMMIT(kEarly, kEarly);
127     CHECK_REFRESH(MIN_EARLY_TRANSACTION_FRAMES - 1, kEarly, kEarly);
128     CHECK_REFRESH(1, kLate, kLate);
129 }
130 
TEST_F(VsyncModulatorTest,EarlyStartAfterEarlyEnd)131 TEST_F(VsyncModulatorTest, EarlyStartAfterEarlyEnd) {
132     const auto token = sp<BBinder>::make();
133     EXPECT_EQ(kEarly, mVsyncModulator->setTransactionSchedule(Schedule::EarlyEnd, token));
134 
135     CHECK_COMMIT(kEarly, kEarly);
136     CHECK_REFRESH(MIN_EARLY_TRANSACTION_FRAMES - 1, kEarly, kEarly);
137 
138     EXPECT_EQ(kEarly, mVsyncModulator->setTransactionSchedule(Schedule::EarlyStart, token));
139 
140     CHECK_COMMIT(kEarly, kEarly);
141     CHECK_REFRESH(1, kEarly, kEarly);
142     CHECK_REFRESH(5 * MIN_EARLY_TRANSACTION_FRAMES, std::nullopt, kEarly);
143 
144     EXPECT_EQ(kEarly, mVsyncModulator->setTransactionSchedule(Schedule::EarlyEnd, token));
145 
146     CHECK_COMMIT(kEarly, kEarly);
147     CHECK_REFRESH(MIN_EARLY_TRANSACTION_FRAMES - 1, kEarly, kEarly);
148     CHECK_REFRESH(1, kLate, kLate);
149 }
150 
TEST_F(VsyncModulatorTest,EarlyStartAfterEarlyEndWithMoreTransactions)151 TEST_F(VsyncModulatorTest, EarlyStartAfterEarlyEndWithMoreTransactions) {
152     const auto token = sp<BBinder>::make();
153     EXPECT_EQ(kEarly, mVsyncModulator->setTransactionSchedule(Schedule::EarlyEnd, token));
154 
155     CHECK_COMMIT(kEarly, kEarly);
156     CHECK_REFRESH(MIN_EARLY_TRANSACTION_FRAMES - 1, kEarly, kEarly);
157 
158     EXPECT_EQ(kEarly, mVsyncModulator->setTransactionSchedule(Schedule::EarlyStart, token));
159 
160     CHECK_COMMIT(kEarly, kEarly);
161     CHECK_REFRESH(1, kEarly, kEarly);
162 
163     for (int i = 0; i < 5 * MIN_EARLY_TRANSACTION_FRAMES; i++) {
164         EXPECT_FALSE(mVsyncModulator->setTransactionSchedule(Schedule::Late));
165         CHECK_REFRESH(1, std::nullopt, kEarly);
166     }
167 
168     EXPECT_EQ(kEarly, mVsyncModulator->setTransactionSchedule(Schedule::EarlyEnd, token));
169 
170     CHECK_COMMIT(kEarly, kEarly);
171     CHECK_REFRESH(MIN_EARLY_TRANSACTION_FRAMES - 1, kEarly, kEarly);
172     CHECK_REFRESH(1, kLate, kLate);
173 }
174 
TEST_F(VsyncModulatorTest,EarlyStartDifferentClients)175 TEST_F(VsyncModulatorTest, EarlyStartDifferentClients) {
176     const auto token1 = sp<BBinder>::make();
177     const auto token2 = sp<BBinder>::make();
178     EXPECT_EQ(kEarly, mVsyncModulator->setTransactionSchedule(Schedule::EarlyStart, token1));
179 
180     CHECK_COMMIT(kEarly, kEarly);
181     CHECK_REFRESH(5 * MIN_EARLY_TRANSACTION_FRAMES, std::nullopt, kEarly);
182 
183     EXPECT_EQ(kEarly, mVsyncModulator->setTransactionSchedule(Schedule::EarlyStart, token2));
184 
185     CHECK_COMMIT(kEarly, kEarly);
186     CHECK_REFRESH(5 * MIN_EARLY_TRANSACTION_FRAMES, std::nullopt, kEarly);
187 
188     EXPECT_EQ(kEarly, mVsyncModulator->setTransactionSchedule(Schedule::EarlyEnd, token1));
189 
190     CHECK_COMMIT(kEarly, kEarly);
191     CHECK_REFRESH(5 * MIN_EARLY_TRANSACTION_FRAMES, std::nullopt, kEarly);
192 
193     EXPECT_EQ(kEarly, mVsyncModulator->setTransactionSchedule(Schedule::EarlyEnd, token2));
194 
195     CHECK_COMMIT(kEarly, kEarly);
196     CHECK_REFRESH(MIN_EARLY_TRANSACTION_FRAMES - 1, kEarly, kEarly);
197     CHECK_REFRESH(1, kLate, kLate);
198 }
199 
TEST_F(VsyncModulatorTest,EarlyStartWithBinderDeath)200 TEST_F(VsyncModulatorTest, EarlyStartWithBinderDeath) {
201     const auto token = sp<BBinder>::make();
202     EXPECT_EQ(kEarly, mVsyncModulator->setTransactionSchedule(Schedule::EarlyStart, token));
203 
204     CHECK_COMMIT(kEarly, kEarly);
205     CHECK_REFRESH(5 * MIN_EARLY_TRANSACTION_FRAMES, std::nullopt, kEarly);
206 
207     mVsyncModulator->binderDied(token);
208 
209     CHECK_COMMIT(std::nullopt, kLate);
210 }
211 
212 } // namespace android::scheduler
213