• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 <JankTracker.h>
18 #include <gmock/gmock.h>
19 #include <gtest/gtest.h>
20 #include <utils/TimeUtils.h>
21 
22 #include "FrameInfo.h"
23 
24 using namespace android;
25 using namespace android::uirenderer;
26 
27 class TestFrameMetricsObserver : public FrameMetricsObserver {
28 public:
notify(const FrameInfoBuffer &)29     void notify(const FrameInfoBuffer&) override {}
30 };
31 
TEST(JankTracker,noJank)32 TEST(JankTracker, noJank) {
33     std::mutex mutex;
34     ProfileDataContainer container(mutex);
35     JankTracker jankTracker(&container);
36     std::unique_ptr<FrameMetricsReporter> reporter = std::make_unique<FrameMetricsReporter>();
37 
38     uint64_t frameNumber = 0;
39     uint32_t surfaceId = 0;
40 
41     FrameInfo* info = jankTracker.startFrame();
42     info->set(FrameInfoIndex::IntendedVsync) = 100_ms;
43     info->set(FrameInfoIndex::Vsync) = 101_ms;
44     info->set(FrameInfoIndex::SwapBuffersCompleted) = 115_ms;
45     info->set(FrameInfoIndex::GpuCompleted) = 115_ms;
46     info->set(FrameInfoIndex::FrameCompleted) = 115_ms;
47     info->set(FrameInfoIndex::FrameInterval) = 16_ms;
48     info->set(FrameInfoIndex::FrameDeadline) = 120_ms;
49     info->set(FrameInfoIndex::WorkloadTarget) = 20_ms;
50     jankTracker.finishFrame(*info, reporter, frameNumber, surfaceId);
51 
52     info = jankTracker.startFrame();
53     info->set(FrameInfoIndex::IntendedVsync) = 116_ms;
54     info->set(FrameInfoIndex::Vsync) = 117_ms;
55     info->set(FrameInfoIndex::SwapBuffersCompleted) = 129_ms;
56     info->set(FrameInfoIndex::GpuCompleted) = 131_ms;
57     info->set(FrameInfoIndex::FrameCompleted) = 131_ms;
58     info->set(FrameInfoIndex::FrameInterval) = 16_ms;
59     info->set(FrameInfoIndex::FrameDeadline) = 136_ms;
60     info->set(FrameInfoIndex::WorkloadTarget) = 20_ms;
61     jankTracker.finishFrame(*info, reporter, frameNumber, surfaceId);
62 
63     ASSERT_EQ(2, container.get()->totalFrameCount());
64     ASSERT_EQ(0, container.get()->jankFrameCount());
65 }
66 
67 
TEST(JankTracker,jank)68 TEST(JankTracker, jank) {
69     std::mutex mutex;
70     ProfileDataContainer container(mutex);
71     JankTracker jankTracker(&container);
72     std::unique_ptr<FrameMetricsReporter> reporter = std::make_unique<FrameMetricsReporter>();
73 
74     uint64_t frameNumber = 0;
75     uint32_t surfaceId = 0;
76 
77     FrameInfo* info = jankTracker.startFrame();
78     info->set(FrameInfoIndex::IntendedVsync) = 100_ms;
79     info->set(FrameInfoIndex::Vsync) = 101_ms;
80     info->set(FrameInfoIndex::SwapBuffersCompleted) = 115_ms;
81     info->set(FrameInfoIndex::GpuCompleted) = 121_ms;
82     info->set(FrameInfoIndex::FrameCompleted) = 121_ms;
83     info->set(FrameInfoIndex::FrameInterval) = 16_ms;
84     info->set(FrameInfoIndex::FrameDeadline) = 120_ms;
85     info->set(FrameInfoIndex::WorkloadTarget) = 20_ms;
86     jankTracker.finishFrame(*info, reporter, frameNumber, surfaceId);
87 
88     ASSERT_EQ(1, container.get()->totalFrameCount());
89     ASSERT_EQ(1, container.get()->jankFrameCount());
90 }
91 
TEST(JankTracker,legacyJankButNoRealJank)92 TEST(JankTracker, legacyJankButNoRealJank) {
93     std::mutex mutex;
94     ProfileDataContainer container(mutex);
95     JankTracker jankTracker(&container);
96     std::unique_ptr<FrameMetricsReporter> reporter = std::make_unique<FrameMetricsReporter>();
97 
98     uint64_t frameNumber = 0;
99     uint32_t surfaceId = 0;
100 
101     FrameInfo* info = jankTracker.startFrame();
102     info->set(FrameInfoIndex::IntendedVsync) = 100_ms;
103     info->set(FrameInfoIndex::Vsync) = 101_ms;
104     info->set(FrameInfoIndex::SwapBuffersCompleted) = 117_ms;
105     info->set(FrameInfoIndex::GpuCompleted) = 118_ms;
106     info->set(FrameInfoIndex::FrameCompleted) = 118_ms;
107     info->set(FrameInfoIndex::FrameInterval) = 16_ms;
108     info->set(FrameInfoIndex::FrameDeadline) = 120_ms;
109     info->set(FrameInfoIndex::WorkloadTarget) = 20_ms;
110     jankTracker.finishFrame(*info, reporter, frameNumber, surfaceId);
111 
112     ASSERT_EQ(1, container.get()->totalFrameCount());
113     ASSERT_EQ(0, container.get()->jankFrameCount());
114     ASSERT_EQ(1, container.get()->jankLegacyFrameCount());
115 }
116 
TEST(JankTracker,doubleStuffed)117 TEST(JankTracker, doubleStuffed) {
118     std::mutex mutex;
119     ProfileDataContainer container(mutex);
120     JankTracker jankTracker(&container);
121     std::unique_ptr<FrameMetricsReporter> reporter = std::make_unique<FrameMetricsReporter>();
122 
123     uint64_t frameNumber = 0;
124     uint32_t surfaceId = 0;
125 
126     // First frame janks
127     FrameInfo* info = jankTracker.startFrame();
128     info->set(FrameInfoIndex::IntendedVsync) = 100_ms;
129     info->set(FrameInfoIndex::Vsync) = 101_ms;
130     info->set(FrameInfoIndex::SwapBuffersCompleted) = 115_ms;
131     info->set(FrameInfoIndex::GpuCompleted) = 121_ms;
132     info->set(FrameInfoIndex::FrameCompleted) = 121_ms;
133     info->set(FrameInfoIndex::FrameInterval) = 16_ms;
134     info->set(FrameInfoIndex::FrameDeadline) = 120_ms;
135     info->set(FrameInfoIndex::WorkloadTarget) = 20_ms;
136     jankTracker.finishFrame(*info, reporter, frameNumber, surfaceId);
137 
138     ASSERT_EQ(1, container.get()->jankFrameCount());
139 
140     // Second frame is long, but doesn't jank because double-stuffed.
141     info = jankTracker.startFrame();
142     info->set(FrameInfoIndex::IntendedVsync) = 116_ms;
143     info->set(FrameInfoIndex::Vsync) = 122_ms;
144     info->set(FrameInfoIndex::SwapBuffersCompleted) = 129_ms;
145     info->set(FrameInfoIndex::GpuCompleted) = 137_ms;
146     info->set(FrameInfoIndex::FrameCompleted) = 137_ms;
147     info->set(FrameInfoIndex::FrameInterval) = 16_ms;
148     info->set(FrameInfoIndex::FrameDeadline) = 136_ms;
149     info->set(FrameInfoIndex::WorkloadTarget) = 20_ms;
150     jankTracker.finishFrame(*info, reporter, frameNumber, surfaceId);
151 
152     ASSERT_EQ(2, container.get()->totalFrameCount());
153     ASSERT_EQ(1, container.get()->jankFrameCount());
154 }
155 
TEST(JankTracker,doubleStuffedThenPauseThenJank)156 TEST(JankTracker, doubleStuffedThenPauseThenJank) {
157     std::mutex mutex;
158     ProfileDataContainer container(mutex);
159     JankTracker jankTracker(&container);
160     std::unique_ptr<FrameMetricsReporter> reporter = std::make_unique<FrameMetricsReporter>();
161 
162     uint64_t frameNumber = 0;
163     uint32_t surfaceId = 0;
164 
165     // First frame janks
166     FrameInfo* info = jankTracker.startFrame();
167     info->set(FrameInfoIndex::IntendedVsync) = 100_ms;
168     info->set(FrameInfoIndex::Vsync) = 101_ms;
169     info->set(FrameInfoIndex::SwapBuffersCompleted) = 115_ms;
170     info->set(FrameInfoIndex::GpuCompleted) = 121_ms;
171     info->set(FrameInfoIndex::FrameCompleted) = 121_ms;
172     info->set(FrameInfoIndex::FrameInterval) = 16_ms;
173     info->set(FrameInfoIndex::FrameDeadline) = 120_ms;
174     info->set(FrameInfoIndex::WorkloadTarget) = 20_ms;
175     jankTracker.finishFrame(*info, reporter, frameNumber, surfaceId);
176 
177     ASSERT_EQ(1, container.get()->jankFrameCount());
178 
179     // Second frame is long, but doesn't jank because double-stuffed.
180     info = jankTracker.startFrame();
181     info->set(FrameInfoIndex::IntendedVsync) = 116_ms;
182     info->set(FrameInfoIndex::Vsync) = 122_ms;
183     info->set(FrameInfoIndex::SwapBuffersCompleted) = 129_ms;
184     info->set(FrameInfoIndex::GpuCompleted) = 137_ms;
185     info->set(FrameInfoIndex::FrameCompleted) = 137_ms;
186     info->set(FrameInfoIndex::FrameInterval) = 16_ms;
187     info->set(FrameInfoIndex::FrameDeadline) = 136_ms;
188     info->set(FrameInfoIndex::WorkloadTarget) = 20_ms;
189     jankTracker.finishFrame(*info, reporter, frameNumber, surfaceId);
190 
191     ASSERT_EQ(1, container.get()->jankFrameCount());
192 
193     // Thirdframe is long and skips one frame some double stuffed logic gets reset
194     info = jankTracker.startFrame();
195     info->set(FrameInfoIndex::IntendedVsync) = 148_ms;
196     info->set(FrameInfoIndex::Vsync) = 148_ms;
197     info->set(FrameInfoIndex::SwapBuffersCompleted) = 160_ms;
198     info->set(FrameInfoIndex::GpuCompleted) = 169_ms;
199     info->set(FrameInfoIndex::FrameCompleted) = 169_ms;
200     info->set(FrameInfoIndex::FrameInterval) = 16_ms;
201     info->set(FrameInfoIndex::FrameDeadline) = 168_ms;
202     info->set(FrameInfoIndex::WorkloadTarget) = 20_ms;
203     jankTracker.finishFrame(*info, reporter, frameNumber, surfaceId);
204 
205     ASSERT_EQ(3, container.get()->totalFrameCount());
206     ASSERT_EQ(2, container.get()->jankFrameCount());
207 }
208 
TEST(JankTracker,doubleStuffedTwoIntervalBehind)209 TEST(JankTracker, doubleStuffedTwoIntervalBehind) {
210     std::mutex mutex;
211     ProfileDataContainer container(mutex);
212     JankTracker jankTracker(&container);
213     std::unique_ptr<FrameMetricsReporter> reporter = std::make_unique<FrameMetricsReporter>();
214 
215     uint64_t frameNumber = 0;
216     uint32_t surfaceId = 0;
217 
218     // First frame janks
219     FrameInfo* info = jankTracker.startFrame();
220     info->set(FrameInfoIndex::IntendedVsync) = 100_ms;
221     info->set(FrameInfoIndex::Vsync) = 101_ms;
222     info->set(FrameInfoIndex::SwapBuffersCompleted) = 107_ms;
223     info->set(FrameInfoIndex::GpuCompleted) = 117_ms;
224     info->set(FrameInfoIndex::FrameCompleted) = 117_ms;
225     info->set(FrameInfoIndex::FrameInterval) = 16_ms;
226     info->set(FrameInfoIndex::FrameDeadline) = 116_ms;
227     info->set(FrameInfoIndex::WorkloadTarget) = 16_ms;
228     jankTracker.finishFrame(*info, reporter, frameNumber, surfaceId);
229 
230     ASSERT_EQ(1, container.get()->jankFrameCount());
231 
232     // Second frame is long, but doesn't jank because double-stuffed.
233     // Second frame duration is between 1*interval ~ 2*interval
234     info = jankTracker.startFrame();
235     info->set(FrameInfoIndex::IntendedVsync) = 116_ms;
236     info->set(FrameInfoIndex::Vsync) = 116_ms;
237     info->set(FrameInfoIndex::SwapBuffersCompleted) = 129_ms;
238     info->set(FrameInfoIndex::GpuCompleted) = 133_ms;
239     info->set(FrameInfoIndex::FrameCompleted) = 133_ms;
240     info->set(FrameInfoIndex::FrameInterval) = 16_ms;
241     info->set(FrameInfoIndex::FrameDeadline) = 132_ms;
242     info->set(FrameInfoIndex::WorkloadTarget) = 16_ms;
243     jankTracker.finishFrame(*info, reporter, frameNumber, surfaceId);
244 
245     ASSERT_EQ(1, container.get()->jankFrameCount());
246 
247     // Third frame is even longer, cause a jank
248     // Third frame duration is between 2*interval ~ 3*interval
249     info = jankTracker.startFrame();
250     info->set(FrameInfoIndex::IntendedVsync) = 132_ms;
251     info->set(FrameInfoIndex::Vsync) = 132_ms;
252     info->set(FrameInfoIndex::SwapBuffersCompleted) = 160_ms;
253     info->set(FrameInfoIndex::GpuCompleted) = 165_ms;
254     info->set(FrameInfoIndex::FrameCompleted) = 165_ms;
255     info->set(FrameInfoIndex::FrameInterval) = 16_ms;
256     info->set(FrameInfoIndex::FrameDeadline) = 148_ms;
257     info->set(FrameInfoIndex::WorkloadTarget) = 16_ms;
258     jankTracker.finishFrame(*info, reporter, frameNumber, surfaceId);
259 
260     ASSERT_EQ(2, container.get()->jankFrameCount());
261 
262     // 4th frame is double-stuffed with a 2 * interval latency
263     // 4th frame duration is between 2*interval ~ 3*interval
264     info = jankTracker.startFrame();
265     info->set(FrameInfoIndex::IntendedVsync) = 148_ms;
266     info->set(FrameInfoIndex::Vsync) = 148_ms;
267     info->set(FrameInfoIndex::SwapBuffersCompleted) = 170_ms;
268     info->set(FrameInfoIndex::GpuCompleted) = 181_ms;
269     info->set(FrameInfoIndex::FrameCompleted) = 181_ms;
270     info->set(FrameInfoIndex::FrameInterval) = 16_ms;
271     info->set(FrameInfoIndex::FrameDeadline) = 164_ms;
272     info->set(FrameInfoIndex::WorkloadTarget) = 16_ms;
273     jankTracker.finishFrame(*info, reporter, frameNumber, surfaceId);
274 
275     ASSERT_EQ(2, container.get()->jankFrameCount());
276 }
277