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 <gtest/gtest.h>
18 #include <gmock/gmock.h>
19 
20 #include <JankTracker.h>
21 #include <utils/TimeUtils.h>
22 
23 using namespace android;
24 using namespace android::uirenderer;
25 
26 class TestFrameMetricsObserver : public FrameMetricsObserver {
27 public:
notify(const int64_t *)28     void notify(const int64_t*) {}
29 };
30 
TEST(JankTracker,noJank)31 TEST(JankTracker, noJank) {
32     std::mutex mutex;
33     ProfileDataContainer container(mutex);
34     JankTracker jankTracker(&container);
35     std::unique_ptr<FrameMetricsReporter> reporter = std::make_unique<FrameMetricsReporter>();
36 
37     FrameInfo* info = jankTracker.startFrame();
38     info->set(FrameInfoIndex::IntendedVsync) = 100_ms;
39     info->set(FrameInfoIndex::Vsync) = 101_ms;
40     info->set(FrameInfoIndex::SwapBuffersCompleted) = 115_ms;
41     info->set(FrameInfoIndex::GpuCompleted) = 115_ms;
42     info->set(FrameInfoIndex::FrameCompleted) = 115_ms;
43     info->set(FrameInfoIndex::FrameInterval) = 16_ms;
44     info->set(FrameInfoIndex::FrameDeadline) = 120_ms;
45     jankTracker.finishFrame(*info, reporter);
46 
47     info = jankTracker.startFrame();
48     info->set(FrameInfoIndex::IntendedVsync) = 116_ms;
49     info->set(FrameInfoIndex::Vsync) = 117_ms;
50     info->set(FrameInfoIndex::SwapBuffersCompleted) = 129_ms;
51     info->set(FrameInfoIndex::GpuCompleted) = 131_ms;
52     info->set(FrameInfoIndex::FrameCompleted) = 131_ms;
53     info->set(FrameInfoIndex::FrameInterval) = 16_ms;
54     info->set(FrameInfoIndex::FrameDeadline) = 136_ms;
55     jankTracker.finishFrame(*info, reporter);
56 
57     ASSERT_EQ(2, container.get()->totalFrameCount());
58     ASSERT_EQ(0, container.get()->jankFrameCount());
59 }
60 
61 
TEST(JankTracker,jank)62 TEST(JankTracker, jank) {
63     std::mutex mutex;
64     ProfileDataContainer container(mutex);
65     JankTracker jankTracker(&container);
66     std::unique_ptr<FrameMetricsReporter> reporter = std::make_unique<FrameMetricsReporter>();
67 
68     FrameInfo* info = jankTracker.startFrame();
69     info->set(FrameInfoIndex::IntendedVsync) = 100_ms;
70     info->set(FrameInfoIndex::Vsync) = 101_ms;
71     info->set(FrameInfoIndex::SwapBuffersCompleted) = 115_ms;
72     info->set(FrameInfoIndex::GpuCompleted) = 121_ms;
73     info->set(FrameInfoIndex::FrameCompleted) = 121_ms;
74     info->set(FrameInfoIndex::FrameInterval) = 16_ms;
75     info->set(FrameInfoIndex::FrameDeadline) = 120_ms;
76     jankTracker.finishFrame(*info, reporter);
77 
78     ASSERT_EQ(1, container.get()->totalFrameCount());
79     ASSERT_EQ(1, container.get()->jankFrameCount());
80 }
81 
TEST(JankTracker,legacyJankButNoRealJank)82 TEST(JankTracker, legacyJankButNoRealJank) {
83     std::mutex mutex;
84     ProfileDataContainer container(mutex);
85     JankTracker jankTracker(&container);
86     std::unique_ptr<FrameMetricsReporter> reporter = std::make_unique<FrameMetricsReporter>();
87 
88     FrameInfo* info = jankTracker.startFrame();
89     info->set(FrameInfoIndex::IntendedVsync) = 100_ms;
90     info->set(FrameInfoIndex::Vsync) = 101_ms;
91     info->set(FrameInfoIndex::SwapBuffersCompleted) = 117_ms;
92     info->set(FrameInfoIndex::GpuCompleted) = 118_ms;
93     info->set(FrameInfoIndex::FrameCompleted) = 118_ms;
94     info->set(FrameInfoIndex::FrameInterval) = 16_ms;
95     info->set(FrameInfoIndex::FrameDeadline) = 120_ms;
96     jankTracker.finishFrame(*info, reporter);
97 
98     ASSERT_EQ(1, container.get()->totalFrameCount());
99     ASSERT_EQ(0, container.get()->jankFrameCount());
100     ASSERT_EQ(1, container.get()->jankLegacyFrameCount());
101 }
102 
TEST(JankTracker,doubleStuffed)103 TEST(JankTracker, doubleStuffed) {
104     std::mutex mutex;
105     ProfileDataContainer container(mutex);
106     JankTracker jankTracker(&container);
107     std::unique_ptr<FrameMetricsReporter> reporter = std::make_unique<FrameMetricsReporter>();
108 
109     // First frame janks
110     FrameInfo* info = jankTracker.startFrame();
111     info->set(FrameInfoIndex::IntendedVsync) = 100_ms;
112     info->set(FrameInfoIndex::Vsync) = 101_ms;
113     info->set(FrameInfoIndex::SwapBuffersCompleted) = 115_ms;
114     info->set(FrameInfoIndex::GpuCompleted) = 121_ms;
115     info->set(FrameInfoIndex::FrameCompleted) = 121_ms;
116     info->set(FrameInfoIndex::FrameInterval) = 16_ms;
117     info->set(FrameInfoIndex::FrameDeadline) = 120_ms;
118     jankTracker.finishFrame(*info, reporter);
119 
120     ASSERT_EQ(1, container.get()->jankFrameCount());
121 
122     // Second frame is long, but doesn't jank because double-stuffed.
123     info = jankTracker.startFrame();
124     info->set(FrameInfoIndex::IntendedVsync) = 116_ms;
125     info->set(FrameInfoIndex::Vsync) = 122_ms;
126     info->set(FrameInfoIndex::SwapBuffersCompleted) = 129_ms;
127     info->set(FrameInfoIndex::GpuCompleted) = 137_ms;
128     info->set(FrameInfoIndex::FrameCompleted) = 137_ms;
129     info->set(FrameInfoIndex::FrameInterval) = 16_ms;
130     info->set(FrameInfoIndex::FrameDeadline) = 136_ms;
131     jankTracker.finishFrame(*info, reporter);
132 
133     ASSERT_EQ(2, container.get()->totalFrameCount());
134     ASSERT_EQ(1, container.get()->jankFrameCount());
135 }
136 
TEST(JankTracker,doubleStuffedThenPauseThenJank)137 TEST(JankTracker, doubleStuffedThenPauseThenJank) {
138     std::mutex mutex;
139     ProfileDataContainer container(mutex);
140     JankTracker jankTracker(&container);
141     std::unique_ptr<FrameMetricsReporter> reporter = std::make_unique<FrameMetricsReporter>();
142 
143     // First frame janks
144     FrameInfo* info = jankTracker.startFrame();
145     info->set(FrameInfoIndex::IntendedVsync) = 100_ms;
146     info->set(FrameInfoIndex::Vsync) = 101_ms;
147     info->set(FrameInfoIndex::SwapBuffersCompleted) = 115_ms;
148     info->set(FrameInfoIndex::GpuCompleted) = 121_ms;
149     info->set(FrameInfoIndex::FrameCompleted) = 121_ms;
150     info->set(FrameInfoIndex::FrameInterval) = 16_ms;
151     info->set(FrameInfoIndex::FrameDeadline) = 120_ms;
152     jankTracker.finishFrame(*info, reporter);
153 
154     ASSERT_EQ(1, container.get()->jankFrameCount());
155 
156     // Second frame is long, but doesn't jank because double-stuffed.
157     info = jankTracker.startFrame();
158     info->set(FrameInfoIndex::IntendedVsync) = 116_ms;
159     info->set(FrameInfoIndex::Vsync) = 122_ms;
160     info->set(FrameInfoIndex::SwapBuffersCompleted) = 129_ms;
161     info->set(FrameInfoIndex::GpuCompleted) = 137_ms;
162     info->set(FrameInfoIndex::FrameCompleted) = 137_ms;
163     info->set(FrameInfoIndex::FrameInterval) = 16_ms;
164     info->set(FrameInfoIndex::FrameDeadline) = 136_ms;
165     jankTracker.finishFrame(*info, reporter);
166 
167     ASSERT_EQ(1, container.get()->jankFrameCount());
168 
169     // Thirdframe is long and skips one frame some double stuffed logic gets reset
170     info = jankTracker.startFrame();
171     info->set(FrameInfoIndex::IntendedVsync) = 148_ms;
172     info->set(FrameInfoIndex::Vsync) = 148_ms;
173     info->set(FrameInfoIndex::SwapBuffersCompleted) = 160_ms;
174     info->set(FrameInfoIndex::GpuCompleted) = 169_ms;
175     info->set(FrameInfoIndex::FrameCompleted) = 169_ms;
176     info->set(FrameInfoIndex::FrameInterval) = 16_ms;
177     info->set(FrameInfoIndex::FrameDeadline) = 168_ms;
178     jankTracker.finishFrame(*info, reporter);
179 
180     ASSERT_EQ(3, container.get()->totalFrameCount());
181     ASSERT_EQ(2, container.get()->jankFrameCount());
182 }