1 // Copyright 2019 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/metrics/frame_sequence_tracker.h"
7 #include "base/test/metrics/histogram_tester.h"
8 #include "cc/metrics/throughput_ukm_reporter.h"
9 #include "cc/trees/ukm_manager.h"
10 #include "components/ukm/test_ukm_recorder.h"
11 #include "testing/gmock/include/gmock/gmock.h"
12 #include "testing/gtest/include/gtest/gtest.h"
16 TEST(FrameSequenceMetricsTest, MergeMetrics) {
17 // Create a metric with only a small number of frames. It shouldn't report any
19 FrameSequenceMetrics first(FrameSequenceTrackerType::kTouchScroll, nullptr);
20 first.impl_throughput().frames_expected = 20;
21 first.impl_throughput().frames_produced = 10;
22 first.impl_throughput().frames_ontime = 5;
23 EXPECT_FALSE(first.HasEnoughDataForReporting());
25 // Create a second metric with too few frames to report any metrics.
26 auto second = std::make_unique<FrameSequenceMetrics>(
27 FrameSequenceTrackerType::kTouchScroll, nullptr);
28 second->impl_throughput().frames_expected = 90;
29 second->impl_throughput().frames_produced = 60;
30 second->impl_throughput().frames_ontime = 50;
31 EXPECT_FALSE(second->HasEnoughDataForReporting());
33 // Merge the two metrics. The result should have enough frames to report
35 first.Merge(std::move(second));
36 EXPECT_TRUE(first.HasEnoughDataForReporting());
40 TEST(FrameSequenceMetricsTest, ScrollingThreadMergeMetrics) {
41 FrameSequenceMetrics first(FrameSequenceTrackerType::kTouchScroll, nullptr);
42 first.SetScrollingThread(FrameInfo::SmoothEffectDrivingThread::kCompositor);
43 first.impl_throughput().frames_expected = 20;
44 first.impl_throughput().frames_produced = 10;
45 first.impl_throughput().frames_ontime = 10;
47 auto second = std::make_unique<FrameSequenceMetrics>(
48 FrameSequenceTrackerType::kTouchScroll, nullptr);
49 second->SetScrollingThread(FrameInfo::SmoothEffectDrivingThread::kMain);
50 second->main_throughput().frames_expected = 50;
51 second->main_throughput().frames_produced = 10;
52 second->main_throughput().frames_ontime = 10;
54 ASSERT_DEATH(first.Merge(std::move(second)), "");
56 #endif // DCHECK_IS_ON()
58 TEST(FrameSequenceMetricsTest, AllMetricsReported) {
59 base::HistogramTester histograms;
61 // Create a metric with enough frames on impl to be reported, but not enough
63 FrameSequenceMetrics first(FrameSequenceTrackerType::kTouchScroll, nullptr);
64 first.impl_throughput().frames_expected = 120;
65 first.impl_throughput().frames_produced = 80;
66 first.impl_throughput().frames_ontime = 60;
67 first.main_throughput().frames_expected = 20;
68 first.main_throughput().frames_produced = 10;
69 first.main_throughput().frames_ontime = 5;
70 EXPECT_TRUE(first.HasEnoughDataForReporting());
71 first.ReportMetrics();
73 // The compositor-thread metric should be reported, but not the main-thread
75 histograms.ExpectTotalCount(
76 "Graphics.Smoothness.PercentDroppedFrames.CompositorThread.TouchScroll",
78 histograms.ExpectTotalCount(
79 "Graphics.Smoothness.PercentDroppedFrames.MainThread.TouchScroll", 0u);
80 histograms.ExpectTotalCount(
81 "Graphics.Smoothness.PercentMissedDeadlineFrames.CompositorThread."
84 histograms.ExpectTotalCount(
85 "Graphics.Smoothness.PercentMissedDeadlineFrames.MainThread.TouchScroll",
88 // There should still be data left over for the main-thread.
89 EXPECT_TRUE(first.HasDataLeftForReporting());
91 auto second = std::make_unique<FrameSequenceMetrics>(
92 FrameSequenceTrackerType::kTouchScroll, nullptr);
93 second->impl_throughput().frames_expected = 110;
94 second->impl_throughput().frames_produced = 100;
95 second->impl_throughput().frames_ontime = 80;
96 second->main_throughput().frames_expected = 90;
97 second->main_throughput().frames_ontime = 70;
98 first.Merge(std::move(second));
99 EXPECT_TRUE(first.HasEnoughDataForReporting());
100 first.ReportMetrics();
101 histograms.ExpectTotalCount(
102 "Graphics.Smoothness.PercentDroppedFrames.CompositorThread.TouchScroll",
104 histograms.ExpectTotalCount(
105 "Graphics.Smoothness.PercentDroppedFrames.MainThread.TouchScroll", 1u);
106 histograms.ExpectTotalCount(
107 "Graphics.Smoothness.PercentMissedDeadlineFrames.CompositorThread."
110 histograms.ExpectTotalCount(
111 "Graphics.Smoothness.PercentMissedDeadlineFrames.MainThread.TouchScroll",
113 // All the metrics have now been reported. No data should be left over.
114 EXPECT_FALSE(first.HasDataLeftForReporting());
117 TEST(FrameSequenceMetricsTest, IrrelevantMetricsNotReported) {
118 base::HistogramTester histograms;
120 // Create a metric with enough frames on impl to be reported, but not enough
122 FrameSequenceMetrics first(FrameSequenceTrackerType::kCompositorAnimation,
124 first.impl_throughput().frames_expected = 120;
125 first.impl_throughput().frames_produced = 80;
126 first.impl_throughput().frames_ontime = 70;
127 first.main_throughput().frames_expected = 120;
128 first.main_throughput().frames_produced = 80;
129 first.main_throughput().frames_ontime = 70;
130 EXPECT_TRUE(first.HasEnoughDataForReporting());
131 first.ReportMetrics();
133 // The compositor-thread metric should be reported, but not the main-thread
134 // or slower-thread metric.
135 histograms.ExpectTotalCount(
136 "Graphics.Smoothness.PercentDroppedFrames.CompositorThread."
137 "CompositorAnimation",
139 histograms.ExpectTotalCount(
140 "Graphics.Smoothness.PercentDroppedFrames.MainThread.CompositorAnimation",
142 histograms.ExpectTotalCount(
143 "Graphics.Smoothness.PercentDroppedFrames.SlowerThread."
144 "CompositorAnimation",
146 histograms.ExpectTotalCount(
147 "Graphics.Smoothness.PercentMissedDeadlineFrames.CompositorThread."
148 "CompositorAnimation",
150 histograms.ExpectTotalCount(
151 "Graphics.Smoothness.PercentMissedDeadlineFrames.MainThread."
152 "CompositorAnimation",
154 histograms.ExpectTotalCount(
155 "Graphics.Smoothness.PercentMissedDeadlineFrames.SlowerThread."
156 "CompositorAnimation",
159 // Not reported, but the data should be reset.
160 EXPECT_EQ(first.impl_throughput().frames_expected, 0u);
161 EXPECT_EQ(first.impl_throughput().frames_produced, 0u);
162 EXPECT_EQ(first.impl_throughput().frames_ontime, 0u);
163 EXPECT_EQ(first.main_throughput().frames_expected, 0u);
164 EXPECT_EQ(first.main_throughput().frames_produced, 0u);
165 EXPECT_EQ(first.main_throughput().frames_ontime, 0u);
167 FrameSequenceMetrics second(FrameSequenceTrackerType::kRAF, nullptr);
168 second.impl_throughput().frames_expected = 120;
169 second.impl_throughput().frames_produced = 80;
170 second.impl_throughput().frames_ontime = 70;
171 second.main_throughput().frames_expected = 120;
172 second.main_throughput().frames_produced = 80;
173 second.main_throughput().frames_ontime = 70;
174 EXPECT_TRUE(second.HasEnoughDataForReporting());
175 second.ReportMetrics();
177 // The main-thread metric should be reported, but not the compositor-thread
178 // or slower-thread metric.
179 histograms.ExpectTotalCount(
180 "Graphics.Smoothness.PercentDroppedFrames.CompositorThread.RAF", 0u);
181 histograms.ExpectTotalCount(
182 "Graphics.Smoothness.PercentDroppedFrames.MainThread.RAF", 1u);
183 histograms.ExpectTotalCount(
184 "Graphics.Smoothness.PercentDroppedFrames.SlowerThread.RAF", 0u);
185 histograms.ExpectTotalCount(
186 "Graphics.Smoothness.PercentMissedDeadlineFrames.CompositorThread.RAF",
188 histograms.ExpectTotalCount(
189 "Graphics.Smoothness.PercentMissedDeadlineFrames.MainThread.RAF", 1u);
190 histograms.ExpectTotalCount(
191 "Graphics.Smoothness.PercentMissedDeadlineFrames.SlowerThread.RAF", 0u);
194 TEST(FrameSequenceMetricsTest, ScrollingThreadMetricsReportedForInteractions) {
196 auto metrics = std::make_unique<FrameSequenceMetrics>(
197 FrameSequenceTrackerType::kTouchScroll, nullptr);
198 metrics->impl_throughput().frames_expected = 100;
199 metrics->impl_throughput().frames_produced = 80;
200 metrics->impl_throughput().frames_ontime = 70;
201 metrics->main_throughput().frames_expected = 100;
202 metrics->main_throughput().frames_produced = 60;
203 metrics->main_throughput().frames_ontime = 50;
207 const char metric[] =
208 "Graphics.Smoothness.PercentDroppedFrames.AllInteractions";
210 // The main-thread metric should be reported in AllInteractions when
211 // main-thread is the scrolling-thread.
212 base::HistogramTester histograms;
213 auto metrics = setup();
214 EXPECT_TRUE(metrics->HasEnoughDataForReporting());
215 metrics->SetScrollingThread(FrameInfo::SmoothEffectDrivingThread::kMain);
216 metrics->ReportMetrics();
217 histograms.ExpectTotalCount(metric, 1u);
218 EXPECT_THAT(histograms.GetAllSamples(metric),
219 testing::ElementsAre(base::Bucket(40, 1)));
222 // The compositor-thread metric should be reported in AllInteractions when
223 // compositor-thread is the scrolling-thread.
224 base::HistogramTester histograms;
225 auto metrics = setup();
226 EXPECT_TRUE(metrics->HasEnoughDataForReporting());
227 metrics->SetScrollingThread(
228 FrameInfo::SmoothEffectDrivingThread::kCompositor);
229 metrics->ReportMetrics();
230 histograms.ExpectTotalCount(metric, 1u);
231 EXPECT_THAT(histograms.GetAllSamples(metric),
232 testing::ElementsAre(base::Bucket(20, 1)));
236 TEST(FrameSequenceMetricsTest, CompositorSharedElementTransitionReported) {
237 base::HistogramTester histograms;
239 auto metrics = std::make_unique<FrameSequenceMetrics>(
240 FrameSequenceTrackerType::kSETCompositorAnimation, nullptr);
241 metrics->impl_throughput().frames_expected = 100;
242 metrics->impl_throughput().frames_produced = 80;
243 metrics->impl_throughput().frames_ontime = 70;
244 metrics->main_throughput().frames_expected = 100;
245 metrics->main_throughput().frames_produced = 60;
246 metrics->main_throughput().frames_ontime = 50;
247 EXPECT_TRUE(metrics->HasEnoughDataForReporting());
248 metrics->ReportMetrics();
249 histograms.ExpectTotalCount(
250 "Graphics.Smoothness.PercentDroppedFrames.CompositorThread."
251 "SETCompositorAnimation",
253 histograms.ExpectTotalCount(
254 "Graphics.Smoothness.PercentDroppedFrames.MainThread."
255 "SETCompositorAnimation",
259 TEST(FrameSequenceMetricsTest, MainThreadSharedElementTransitionReported) {
260 base::HistogramTester histograms;
262 auto metrics = std::make_unique<FrameSequenceMetrics>(
263 FrameSequenceTrackerType::kSETMainThreadAnimation, nullptr);
264 metrics->impl_throughput().frames_expected = 100;
265 metrics->impl_throughput().frames_produced = 80;
266 metrics->impl_throughput().frames_ontime = 70;
267 metrics->main_throughput().frames_expected = 100;
268 metrics->main_throughput().frames_produced = 60;
269 metrics->main_throughput().frames_ontime = 50;
270 EXPECT_TRUE(metrics->HasEnoughDataForReporting());
271 metrics->ReportMetrics();
272 histograms.ExpectTotalCount(
273 "Graphics.Smoothness.PercentDroppedFrames.CompositorThread."
274 "SETMainThreadAnimation",
276 histograms.ExpectTotalCount(
277 "Graphics.Smoothness.PercentDroppedFrames.MainThread."
278 "SETMainThreadAnimation",