[M108 Migration][VD] Avoid pending frame counter becoming negative
[platform/framework/web/chromium-efl.git] / cc / metrics / jank_metrics_unittest.cc
1 // Copyright 2020 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.
4
5 #include "cc/metrics/jank_metrics.h"
6
7 #include <memory>
8 #include <string>
9 #include <unordered_map>
10 #include <utility>
11 #include <vector>
12
13 #include "base/strings/strcat.h"
14 #include "base/test/metrics/histogram_tester.h"
15 #include "cc/metrics/frame_sequence_tracker.h"
16 #include "cc/metrics/throughput_ukm_reporter.h"
17 #include "cc/trees/ukm_manager.h"
18 #include "components/ukm/test_ukm_recorder.h"
19 #include "testing/gmock/include/gmock/gmock.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21
22 namespace {
23 const base::TimeDelta kDefaultFrameInterval = base::Milliseconds(16.67);
24
25 // All sequence numbers for simulated frame events will start at this number.
26 // This makes it easier to numerically distinguish sequence numbers versus
27 // frame tokens, which always start at 1.
28 const uint32_t kSequenceNumberStartsAt = 100u;
29
30 const char* kAllSequencesMetricName = "Graphics.Smoothness.Jank.AllSequences";
31 const char* kAllAnimationsMetricName = "Graphics.Smoothness.Jank.AllAnimations";
32 const char* kAllInteractionsMetricName =
33     "Graphics.Smoothness.Jank.AllInteractions";
34
35 }  // namespace
36
37 namespace cc {
38
39 class JankMetricsTest : public testing::Test {
40  public:
41   JankMetricsTest() = default;
42   ~JankMetricsTest() override = default;
43
44   // Simulate a series of Submit, NoUpdate, and Presentation events and notify
45   // |jank_reporter|, as specified by |frame_sequences|. The exact presentation
46   // time of frames can be slightly manipulated by |presentation_time_shifts|.
47   void SimulateFrameSequence(
48       JankMetrics* jank_reporter,
49       const std::array<std::string, 3>& frame_sequences,
50       const std::unordered_map<char, double>& presentation_time_shifts = {}) {
51     // |frame_sequences| is an array of 3 strings of EQUAL LENGTH, representing
52     // the (S)UBMIT, (N)O-UPDATE, (P)RESENTATION events, respectively. In all 3
53     // strings:
54     //   any char == a vsync interval (16.67ms) with a unique sequence number.
55     //   '-' == no event in this vsync interval.
56     // In SUBMIT string:
57     //   [a-zA-Z] == A SUBMIT occurs at this vsync interval. Each symbol in this
58     //   string must be unique.
59     // In NO-UPDATE string:
60     //   Any non '-' letter == A NO-UPDATE frame is reported at this vsync
61     //   interval.
62     // In PRESENTATION string:
63     //   [a-zA-Z] == A PRESENTATION occurs at this vsync interval. Each
64     //   symbol must be unique and MUST HAVE APPEARED in the SUBMIT string.
65     //
66     // NOTE this test file stylistically denotes the frames that should jank
67     // with uppercases (although this is not a strict).
68     //
69     // Each item in |presentation_time_shifts| maps a presentation frame letter
70     // (must have appeared in string P) to how much time (in ms) this
71     // presentation deviates from expected. For example: {'a': -3.2} means frame
72     // 'a' is presented 3.2ms before expected.
73     //
74     // e.g.
75     // S = "a-b--c--D--"
76     // N = "---**------"
77     // P = "-a-b---c-D-"
78     // presentation_time_shifts = {'c':-8.4, 'D':8.4}
79     //
80     // means submit at vsync 0, 2, 5, 8, presentation at 1, 3, 7, 9. Due to the
81     // no-update frames 3 and 4, no janks will be reported for 'c'. However, the
82     // large fluctuation of presentation time of 'c' and 'D', there is a jank
83     // at 'D'.
84     //
85     // Without the no-update frames and presentation_time_shifts, one jank would
86     // have been reported at 'c'.
87     auto& submits = frame_sequences[0];
88     auto& ignores = frame_sequences[1];
89     auto& presnts = frame_sequences[2];
90
91     // All three sequences must have the same size.
92     EXPECT_EQ(submits.size(), ignores.size());
93     EXPECT_EQ(submits.size(), presnts.size());
94
95     // Map submitted frame to their tokens
96     std::unordered_map<char, uint32_t> submit_to_token;
97
98     base::TimeTicks start_time = base::TimeTicks::Now();
99
100     // Scan S to collect all symbols
101     for (uint32_t frame_token = 1, i = 0; i < submits.size(); ++i) {
102       uint32_t sequence_number = kSequenceNumberStartsAt + i;
103       if (submits[i] != '-') {
104         submit_to_token[submits[i]] = frame_token;
105         jank_reporter->AddSubmitFrame(/*frame_token=*/frame_token,
106                                       /*sequence_number=*/sequence_number);
107         frame_token++;
108       }
109
110       if (ignores[i] != '-') {
111         jank_reporter->AddFrameWithNoUpdate(
112             /*sequence_number=*/sequence_number,
113             /*frame_interval=*/kDefaultFrameInterval);
114       }
115
116       if (presnts[i] != '-') {
117         // The present frame must have been previously submitted
118         EXPECT_EQ(submit_to_token.count(presnts[i]), 1u);
119
120         double presentation_offset = 0.0;  // ms
121         if (presentation_time_shifts.count(presnts[i]))
122           presentation_offset = presentation_time_shifts.at(presnts[i]);
123
124         jank_reporter->AddPresentedFrame(
125             /*presented_frame_token=*/submit_to_token[presnts[i]],
126             /*current_presentation_timestamp=*/start_time +
127                 i * kDefaultFrameInterval +
128                 base::Milliseconds(presentation_offset),
129             /*frame_interval=*/kDefaultFrameInterval);
130         submit_to_token.erase(presnts[i]);
131       }
132     }
133   }
134 };
135
136 TEST_F(JankMetricsTest, CompositorAnimationOneJankWithMildFluctuation) {
137   base::HistogramTester histogram_tester;
138   FrameSequenceTrackerType tracker_type =
139       FrameSequenceTrackerType::kCompositorAnimation;
140   FrameInfo::SmoothEffectDrivingThread thread_type =
141       FrameInfo::SmoothEffectDrivingThread::kCompositor;
142   JankMetrics jank_reporter{tracker_type, thread_type};
143
144   // One Jank; there are no no-update frames. The fluctuation in presentation of
145   // 'd' is not big enough to cause another jank.
146   SimulateFrameSequence(&jank_reporter,
147                         {
148                             /*submit   */ "ab-C-d",
149                             /*noupdate */ "------",
150                             /*present  */ "ab-C-d",
151                         },
152                         {{'d', +8.0 /*ms*/}});
153   jank_reporter.ReportJankMetrics(100u);
154
155   // One sample of 1 janks reported for "Compositor".
156   const char* metric =
157       "Graphics.Smoothness.Jank.Compositor.CompositorAnimation";
158   const char* invalid_metric =
159       "Graphics.Smoothness.Jank.Main.CompositorAnimation";
160
161   histogram_tester.ExpectTotalCount(metric, 1u);
162   EXPECT_THAT(histogram_tester.GetAllSamples(metric),
163               testing::ElementsAre(base::Bucket(1, 1)));
164
165   // Test all-sequence metrics.
166   histogram_tester.ExpectTotalCount(kAllSequencesMetricName, 1u);
167   EXPECT_THAT(histogram_tester.GetAllSamples(kAllSequencesMetricName),
168               testing::ElementsAre(base::Bucket(1, 1)));
169
170   histogram_tester.ExpectTotalCount(kAllAnimationsMetricName, 1u);
171   EXPECT_THAT(histogram_tester.GetAllSamples(kAllSequencesMetricName),
172               testing::ElementsAre(base::Bucket(1, 1)));
173
174   histogram_tester.ExpectTotalCount(kAllInteractionsMetricName, 0u);
175
176   // Stale-frame metrics
177   const char* stale_metric = "Graphics.Smoothness.Stale.CompositorAnimation";
178   const char* maxstale_metric =
179       "Graphics.Smoothness.MaxStale.CompositorAnimation";
180
181   histogram_tester.ExpectTotalCount(stale_metric, 3u);
182   EXPECT_THAT(
183       histogram_tester.GetAllSamples(stale_metric),
184       testing::ElementsAre(base::Bucket(0, 1), base::Bucket(16, 1),
185                            base::Bucket(24, 1) /*caused by +8ms fluctuation*/));
186
187   histogram_tester.ExpectTotalCount(maxstale_metric, 1u);
188   EXPECT_THAT(histogram_tester.GetAllSamples(maxstale_metric),
189               testing::ElementsAre(base::Bucket(24, 1)));
190
191   // No reporting for "Main".
192   histogram_tester.ExpectTotalCount(invalid_metric, 0u);
193 }
194
195 TEST_F(JankMetricsTest, MainThreadAnimationOneJankWithNoUpdate) {
196   base::HistogramTester histogram_tester;
197   FrameSequenceTrackerType tracker_type =
198       FrameSequenceTrackerType::kMainThreadAnimation;
199   FrameInfo::SmoothEffectDrivingThread thread_type =
200       FrameInfo::SmoothEffectDrivingThread::kMain;
201   JankMetrics jank_reporter{tracker_type, thread_type};
202
203   // There are only 1 jank because of a no-update frame.
204
205   SimulateFrameSequence(&jank_reporter, {
206                                             /*submit   */ "ab-c--D",
207                                             /*noupdate */ "--*----",
208                                             /*present  */ "ab-c--D",
209                                         });
210   jank_reporter.ReportJankMetrics(100u);
211
212   // One jank is reported for "Main".
213   const char* metric = "Graphics.Smoothness.Jank.Main.MainThreadAnimation";
214   const char* invalid_metric =
215       "Graphics.Smoothness.Jank.Compositor.MainThreadAnimation";
216
217   histogram_tester.ExpectTotalCount(metric, 1u);
218   EXPECT_THAT(histogram_tester.GetAllSamples(metric),
219               testing::ElementsAre(base::Bucket(1, 1)));
220
221   // No jank is reported for "Compositor"
222   histogram_tester.ExpectTotalCount(invalid_metric, 0u);
223
224   // Test all-sequence metrics.
225   histogram_tester.ExpectTotalCount(kAllSequencesMetricName, 1u);
226   EXPECT_THAT(histogram_tester.GetAllSamples(kAllSequencesMetricName),
227               testing::ElementsAre(base::Bucket(1, 1)));
228
229   histogram_tester.ExpectTotalCount(kAllAnimationsMetricName, 1u);
230   EXPECT_THAT(histogram_tester.GetAllSamples(kAllSequencesMetricName),
231               testing::ElementsAre(base::Bucket(1, 1)));
232
233   histogram_tester.ExpectTotalCount(kAllInteractionsMetricName, 0u);
234
235   // Stale-frame metrics
236   const char* stale_metric = "Graphics.Smoothness.Stale.MainThreadAnimation";
237   const char* maxstale_metric =
238       "Graphics.Smoothness.MaxStale.MainThreadAnimation";
239
240   histogram_tester.ExpectTotalCount(stale_metric, 3u);
241   EXPECT_THAT(histogram_tester.GetAllSamples(stale_metric),
242               testing::ElementsAre(base::Bucket(0, 2), base::Bucket(33, 1)));
243
244   histogram_tester.ExpectTotalCount(maxstale_metric, 1u);
245   EXPECT_THAT(histogram_tester.GetAllSamples(maxstale_metric),
246               testing::ElementsAre(base::Bucket(33, 1)));
247 }
248
249 TEST_F(JankMetricsTest, VideoManyJanksOver300ExpectedFrames) {
250   base::HistogramTester histogram_tester;
251   FrameSequenceTrackerType tracker_type = FrameSequenceTrackerType::kVideo;
252   FrameInfo::SmoothEffectDrivingThread thread_type =
253       FrameInfo::SmoothEffectDrivingThread::kCompositor;
254   JankMetrics jank_reporter{tracker_type, thread_type};
255
256   // 7 janks.
257   SimulateFrameSequence(&jank_reporter,
258                         {
259                             /*submit   */ "ab-C--DeFGh-IJk---L---------",
260                             /*noupdate */ "----------------------------",
261                             /*present  */ "---ab-C--De-F--Gh-I---Jk---L",
262                         });
263
264   jank_reporter.ReportJankMetrics(300u);
265
266   // Report in the 7/300 ~= 2% bucket for "Compositor"
267   const char* metric = "Graphics.Smoothness.Jank.Compositor.Video";
268   const char* invalid_metric = "Graphics.Smoothness.Jank.Main.Video";
269
270   histogram_tester.ExpectTotalCount(metric, 1u);
271   EXPECT_THAT(histogram_tester.GetAllSamples(metric),
272               testing::ElementsAre(base::Bucket(2, 1)));
273
274   // No jank is reported for "Main"
275   histogram_tester.ExpectTotalCount(invalid_metric, 0u);
276
277   // Test all-sequence metrics. Videos are not counted into AllSequences.
278   histogram_tester.ExpectTotalCount(kAllSequencesMetricName, 0u);
279   histogram_tester.ExpectTotalCount(kAllAnimationsMetricName, 0u);
280   histogram_tester.ExpectTotalCount(kAllInteractionsMetricName, 0u);
281
282   // Stale-frame metrics
283   const char* stale_metric = "Graphics.Smoothness.Stale.Video";
284   const char* maxstale_metric = "Graphics.Smoothness.MaxStale.Video";
285
286   histogram_tester.ExpectTotalCount(stale_metric, 11u);
287   EXPECT_THAT(histogram_tester.GetAllSamples(stale_metric),
288               testing::ElementsAre(base::Bucket(0, 4), base::Bucket(16, 3),
289                                    base::Bucket(33, 2), base::Bucket(50, 2)));
290
291   histogram_tester.ExpectTotalCount(maxstale_metric, 1u);
292   EXPECT_THAT(histogram_tester.GetAllSamples(maxstale_metric),
293               testing::ElementsAre(base::Bucket(50, 1)));
294 }
295
296 TEST_F(JankMetricsTest, WheelScrollMainThreadNoJanksWithNoUpdates) {
297   base::HistogramTester histogram_tester;
298   FrameSequenceTrackerType tracker_type =
299       FrameSequenceTrackerType::kWheelScroll;
300   FrameInfo::SmoothEffectDrivingThread thread_type =
301       FrameInfo::SmoothEffectDrivingThread::kMain;
302   JankMetrics jank_reporter{tracker_type, thread_type};
303
304   SimulateFrameSequence(&jank_reporter,
305                         {
306                             /*submit   */ "ab-c--d------e---------f-",
307                             /*noupdate */ "--*-**-******-*********--",
308                             /*present  */ "---ab-c-d-----e---------f",
309                         });
310   jank_reporter.ReportJankMetrics(100u);
311
312   // Expect 2 janks for "Main" and no jank for "Compositor"
313   const char* metric = "Graphics.Smoothness.Jank.Main.WheelScroll";
314   const char* invalid_metric =
315       "Graphics.Smoothness.Jank.Compositor.WheelScroll";
316
317   histogram_tester.ExpectTotalCount(metric, 1u);
318   EXPECT_THAT(histogram_tester.GetAllSamples(metric),
319               testing::ElementsAre(base::Bucket(0, 1)));
320
321   histogram_tester.ExpectTotalCount(invalid_metric, 0u);
322
323   // Test all-sequence metrics.
324   histogram_tester.ExpectTotalCount(kAllSequencesMetricName, 1u);
325   EXPECT_THAT(histogram_tester.GetAllSamples(kAllSequencesMetricName),
326               testing::ElementsAre(base::Bucket(0, 1)));
327
328   histogram_tester.ExpectTotalCount(kAllAnimationsMetricName, 0u);
329
330   histogram_tester.ExpectTotalCount(kAllInteractionsMetricName, 1u);
331   EXPECT_THAT(histogram_tester.GetAllSamples(kAllInteractionsMetricName),
332               testing::ElementsAre(base::Bucket(0, 1)));
333
334   // Stale-frame metrics
335   const char* stale_metric = "Graphics.Smoothness.Stale.WheelScroll";
336   const char* maxstale_metric = "Graphics.Smoothness.MaxStale.WheelScroll";
337
338   histogram_tester.ExpectTotalCount(stale_metric, 5u);
339   EXPECT_THAT(histogram_tester.GetAllSamples(stale_metric),
340               testing::ElementsAre(base::Bucket(0, 5)));
341
342   histogram_tester.ExpectTotalCount(maxstale_metric, 1u);
343   EXPECT_THAT(histogram_tester.GetAllSamples(maxstale_metric),
344               testing::ElementsAre(base::Bucket(0, 1)));
345 }
346
347 TEST_F(JankMetricsTest, WheelScrollCompositorTwoJanksWithLargeFluctuation) {
348   base::HistogramTester histogram_tester;
349   FrameSequenceTrackerType tracker_type =
350       FrameSequenceTrackerType::kWheelScroll;
351   FrameInfo::SmoothEffectDrivingThread thread_type =
352       FrameInfo::SmoothEffectDrivingThread::kCompositor;
353   JankMetrics jank_reporter{tracker_type, thread_type};
354
355   // Two janks; there are no no-update frames. The fluctuations in presentation
356   // of 'C' and 'D' are just big enough to cause another jank.
357   SimulateFrameSequence(&jank_reporter,
358                         {
359                             /*submit   */ "ab-C-D",
360                             /*noupdate */ "------",
361                             /*present  */ "ab-C-D",
362                         },
363                         {{'C', -2.0 /*ms*/}, {'D', +7.0 /*ms*/}});
364   jank_reporter.ReportJankMetrics(100u);
365
366   // One sample of 2 janks reported for "Compositor".
367   const char* metric = "Graphics.Smoothness.Jank.Compositor.WheelScroll";
368   const char* invalid_metric = "Graphics.Smoothness.Jank.Main.WheelScroll";
369
370   histogram_tester.ExpectTotalCount(metric, 1u);
371   EXPECT_THAT(histogram_tester.GetAllSamples(metric),
372               testing::ElementsAre(base::Bucket(2, 1)));
373
374   // No reporting for "Main".
375   histogram_tester.ExpectTotalCount(invalid_metric, 0u);
376
377   // Test all-sequence metrics.
378   histogram_tester.ExpectTotalCount(kAllSequencesMetricName, 1u);
379   EXPECT_THAT(histogram_tester.GetAllSamples(kAllSequencesMetricName),
380               testing::ElementsAre(base::Bucket(2, 1)));
381
382   histogram_tester.ExpectTotalCount(kAllAnimationsMetricName, 0u);
383
384   histogram_tester.ExpectTotalCount(kAllInteractionsMetricName, 1u);
385   EXPECT_THAT(histogram_tester.GetAllSamples(kAllInteractionsMetricName),
386               testing::ElementsAre(base::Bucket(2, 1)));
387
388   // Stale-frame metrics
389   const char* stale_metric = "Graphics.Smoothness.Stale.WheelScroll";
390   const char* maxstale_metric = "Graphics.Smoothness.MaxStale.WheelScroll";
391
392   histogram_tester.ExpectTotalCount(stale_metric, 3u);
393   EXPECT_THAT(histogram_tester.GetAllSamples(stale_metric),
394               testing::ElementsAre(
395                   base::Bucket(0, 1), base::Bucket(14, 1), /*-2ms fluctuation*/
396                   base::Bucket(25, 1) /*+7ms - (-2)ms = +9ms fluctuation*/));
397
398   histogram_tester.ExpectTotalCount(maxstale_metric, 1u);
399   EXPECT_THAT(histogram_tester.GetAllSamples(maxstale_metric),
400               testing::ElementsAre(base::Bucket(25, 1)));
401 }
402
403 TEST_F(JankMetricsTest, TouchScrollCompositorThreadManyJanksLongLatency) {
404   base::HistogramTester histogram_tester;
405   FrameSequenceTrackerType tracker_type =
406       FrameSequenceTrackerType::kTouchScroll;
407   FrameInfo::SmoothEffectDrivingThread thread_type =
408       FrameInfo::SmoothEffectDrivingThread::kCompositor;
409
410   JankMetrics jank_reporter{tracker_type, thread_type};
411
412   // There are long delays from submit to presentations.
413   SimulateFrameSequence(
414       &jank_reporter,
415       {
416           /*submit   */ "abB-c--D--EFgH----------------------",
417           /*noupdate */ "---*--------------------------------",
418           /*present  */ "----------ab-B--c---D----E-----Fg--H",
419       },
420       {{'F', -3.0 /*ms*/}});
421   jank_reporter.ReportJankMetrics(120u);
422
423   // Expect janks in the 5/120 ~= 4% bucket for "Compositor", and no jank
424   // for "Main"
425   const char* metric = "Graphics.Smoothness.Jank.Compositor.TouchScroll";
426   const char* invalid_metric = "Graphics.Smoothness.Jank.Main.TouchScroll";
427
428   histogram_tester.ExpectTotalCount(metric, 1u);
429   EXPECT_THAT(histogram_tester.GetAllSamples(metric),
430               testing::ElementsAre(base::Bucket(4, 1)));
431
432   histogram_tester.ExpectTotalCount(invalid_metric, 0u);
433
434   // Test all-sequence metrics.
435   histogram_tester.ExpectTotalCount(kAllSequencesMetricName, 1u);
436   EXPECT_THAT(histogram_tester.GetAllSamples(kAllSequencesMetricName),
437               testing::ElementsAre(base::Bucket(4, 1)));
438
439   histogram_tester.ExpectTotalCount(kAllAnimationsMetricName, 0u);
440
441   histogram_tester.ExpectTotalCount(kAllInteractionsMetricName, 1u);
442   EXPECT_THAT(histogram_tester.GetAllSamples(kAllInteractionsMetricName),
443               testing::ElementsAre(base::Bucket(4, 1)));
444
445   // Stale-frame metrics
446   const char* stale_metric = "Graphics.Smoothness.Stale.TouchScroll";
447   const char* maxstale_metric = "Graphics.Smoothness.MaxStale.TouchScroll";
448
449   histogram_tester.ExpectTotalCount(stale_metric, 8u);
450   EXPECT_THAT(histogram_tester.GetAllSamples(stale_metric),
451               testing::ElementsAre(
452                   base::Bucket(0, 1), base::Bucket(3, 1), /* F to g */
453                   base::Bucket(16, 2), base::Bucket(33, 1), base::Bucket(50, 1),
454                   base::Bucket(66, 1), base::Bucket(80, 1) /* E to F */));
455
456   histogram_tester.ExpectTotalCount(maxstale_metric, 1u);
457   EXPECT_THAT(histogram_tester.GetAllSamples(maxstale_metric),
458               testing::ElementsAre(base::Bucket(80, 1)));
459 }
460
461 // Test if the jank reporter can correctly merge janks from another jank
462 // reporter.
463 TEST_F(JankMetricsTest, RAFMergeJanks) {
464   base::HistogramTester histogram_tester;
465   FrameSequenceTrackerType tracker_type = FrameSequenceTrackerType::kRAF;
466   FrameInfo::SmoothEffectDrivingThread thread_type =
467       FrameInfo::SmoothEffectDrivingThread::kMain;
468
469   JankMetrics jank_reporter{tracker_type, thread_type};
470   std::unique_ptr<JankMetrics> other_reporter =
471       std::make_unique<JankMetrics>(tracker_type, thread_type);
472
473   std::array<std::string, 3> seqs = {
474       /*submit   */ "a-b-Cd-e-F--D-",
475       /*noupdate */ "-*----*-------",
476       /*present  */ "-a-b-Cd-e-F--D",
477   };
478   SimulateFrameSequence(&jank_reporter, seqs);
479   SimulateFrameSequence(other_reporter.get(), seqs);
480
481   jank_reporter.Merge(std::move(other_reporter));
482   EXPECT_EQ(jank_reporter.jank_count(), 6);
483   EXPECT_TRUE(jank_reporter.max_staleness() > base::Milliseconds(33) &&
484               jank_reporter.max_staleness() < base::Milliseconds(34));
485   jank_reporter.ReportJankMetrics(100u);
486
487   // Jank / staleness values should be reset after reporting
488   EXPECT_EQ(jank_reporter.jank_count(), 0);
489   EXPECT_EQ(jank_reporter.max_staleness(), base::Milliseconds(0));
490
491   // Expect 6 janks for "Main" (3 from each reporter)
492   const char* metric = "Graphics.Smoothness.Jank.Main.RAF";
493   const char* invalid_metric = "Graphics.Smoothness.Jank.Compositor.RAF";
494
495   histogram_tester.ExpectTotalCount(metric, 1u);
496   EXPECT_THAT(histogram_tester.GetAllSamples(metric),
497               testing::ElementsAre(base::Bucket(6, 1)));
498
499   histogram_tester.ExpectTotalCount(invalid_metric, 0u);
500
501   // Test all-sequence metrics.
502   // RAF is not included in AllSequences/AllAnimations metrics.
503   histogram_tester.ExpectTotalCount(kAllSequencesMetricName, 0u);
504   histogram_tester.ExpectTotalCount(kAllAnimationsMetricName, 0u);
505   histogram_tester.ExpectTotalCount(kAllInteractionsMetricName, 0u);
506
507   // Stale-frame metrics
508   const char* stale_metric = "Graphics.Smoothness.Stale.RAF";
509   const char* maxstale_metric = "Graphics.Smoothness.MaxStale.RAF";
510
511   histogram_tester.ExpectTotalCount(stale_metric, 12u);
512   EXPECT_THAT(histogram_tester.GetAllSamples(stale_metric),
513               testing::ElementsAre(base::Bucket(0, 6), base::Bucket(16, 4),
514                                    base::Bucket(33, 2)));
515
516   histogram_tester.ExpectTotalCount(maxstale_metric, 1u);
517   EXPECT_THAT(histogram_tester.GetAllSamples(maxstale_metric),
518               testing::ElementsAre(base::Bucket(33, 1)));
519 }
520
521 // Test if jank reporting is correctly disabled for Custom trackers.
522 TEST_F(JankMetricsTest, CustomNotReported) {
523   base::HistogramTester histogram_tester;
524   FrameSequenceTrackerType tracker_type = FrameSequenceTrackerType::kCustom;
525   FrameInfo::SmoothEffectDrivingThread thread_type =
526       FrameInfo::SmoothEffectDrivingThread::kMain;
527   JankMetrics jank_reporter{tracker_type, thread_type};
528
529   // There should be 4 janks, but the jank reporter does not track or report
530   // them.
531   SimulateFrameSequence(&jank_reporter, {
532                                             /*submit   */ "ab-C--D---E----F",
533                                             /*noupdate */ "----------------",
534                                             /*present  */ "ab-C--D---E----F",
535                                         });
536   jank_reporter.ReportJankMetrics(100u);
537
538   // Expect no jank reports even though the sequence contains jank
539   histogram_tester.ExpectTotalCount("Graphics.Smoothness.Jank.Main.Custom", 0u);
540   histogram_tester.ExpectTotalCount(
541       "Graphics.Smoothness.Jank.Compositor.Custom", 0u);
542
543   // Test all-sequence metrics.
544   histogram_tester.ExpectTotalCount(kAllSequencesMetricName, 0u);
545   histogram_tester.ExpectTotalCount(kAllAnimationsMetricName, 0u);
546   histogram_tester.ExpectTotalCount(kAllInteractionsMetricName, 0u);
547
548   // Stale-frame metrics
549   histogram_tester.ExpectTotalCount("Graphics.Smoothness.Stale.Custom", 0u);
550   histogram_tester.ExpectTotalCount("Graphics.Smoothness.MaxStale.Custom", 0u);
551 }
552
553 // Test a frame sequence with a long idle period >= 100 frames.
554 // The presentation interval containing the idle period is excluded from
555 // jank/stale calculation since the length of the idle period reaches a
556 // predefined cap.
557 TEST_F(JankMetricsTest, CompositorAnimationOneJankWithLongIdlePeriod) {
558   base::HistogramTester histogram_tester;
559   FrameSequenceTrackerType tracker_type =
560       FrameSequenceTrackerType::kCompositorAnimation;
561   FrameInfo::SmoothEffectDrivingThread thread_type =
562       FrameInfo::SmoothEffectDrivingThread::kCompositor;
563   JankMetrics jank_reporter{tracker_type, thread_type};
564
565   // One jank at E. The long delay of 100 frames between b and c is considered
566   // a long idle period and therefore does not participate in jank/stale
567   // calculation.
568   SimulateFrameSequence(&jank_reporter,
569                         {
570                             /*submit   */ std::string("a-b") +
571                                 std::string(100, '-') + std::string("c--d---E"),
572                             /*noupdate */ std::string("---") +
573                                 std::string(100, '*') + std::string("--------"),
574                             /*present  */ std::string("a-b") +
575                                 std::string(100, '-') + std::string("c--d---E"),
576                         },
577                         {});
578   jank_reporter.ReportJankMetrics(100u);
579
580   // One sample of 1 janks reported for "Compositor".
581   const char* metric =
582       "Graphics.Smoothness.Jank.Compositor.CompositorAnimation";
583   const char* invalid_metric =
584       "Graphics.Smoothness.Jank.Main.CompositorAnimation";
585
586   histogram_tester.ExpectTotalCount(metric, 1u);
587   EXPECT_THAT(histogram_tester.GetAllSamples(metric),
588               testing::ElementsAre(base::Bucket(1, 1)));
589
590   // Test all-sequence metrics.
591   histogram_tester.ExpectTotalCount(kAllSequencesMetricName, 1u);
592   EXPECT_THAT(histogram_tester.GetAllSamples(kAllSequencesMetricName),
593               testing::ElementsAre(base::Bucket(1, 1)));
594
595   histogram_tester.ExpectTotalCount(kAllAnimationsMetricName, 1u);
596   EXPECT_THAT(histogram_tester.GetAllSamples(kAllSequencesMetricName),
597               testing::ElementsAre(base::Bucket(1, 1)));
598
599   histogram_tester.ExpectTotalCount(kAllInteractionsMetricName, 0u);
600
601   // Stale-frame metrics
602   const char* stale_metric = "Graphics.Smoothness.Stale.CompositorAnimation";
603   const char* maxstale_metric =
604       "Graphics.Smoothness.MaxStale.CompositorAnimation";
605
606   histogram_tester.ExpectTotalCount(stale_metric, 4u);
607   EXPECT_THAT(
608       histogram_tester.GetAllSamples(stale_metric),
609       testing::ElementsAre(base::Bucket(0, 1),  /* The long frame from b to c*/
610                            base::Bucket(16, 1), /* a-b */
611                            base::Bucket(33, 1), /* c--d */
612                            base::Bucket(50, 1)) /* d---E */);
613   histogram_tester.ExpectTotalCount(maxstale_metric, 1u);
614   EXPECT_THAT(histogram_tester.GetAllSamples(maxstale_metric),
615               testing::ElementsAre(base::Bucket(50, 1)));
616
617   // No reporting for "Main".
618   histogram_tester.ExpectTotalCount(invalid_metric, 0u);
619 }
620
621 // Test a frame sequence with an idle period < 100 frames.
622 // The jank and stale are still calculated normally in this case.
623 TEST_F(JankMetricsTest, CompositorAnimationTwoJanksWithModerateIdlePeriod) {
624   base::HistogramTester histogram_tester;
625   FrameSequenceTrackerType tracker_type =
626       FrameSequenceTrackerType::kCompositorAnimation;
627   FrameInfo::SmoothEffectDrivingThread thread_type =
628       FrameInfo::SmoothEffectDrivingThread::kCompositor;
629   JankMetrics jank_reporter{tracker_type, thread_type};
630
631   // Two janks at D and E. The long delay of 99 no-update frames does not
632   // exceed the capacity of the no-update frame queue and therefore is not
633   // excluded from jank/stale calculation.
634   SimulateFrameSequence(&jank_reporter,
635                         {
636                             /*submit   */ std::string("a-b-") +
637                                 std::string(99, '-') + std::string("c--D---E"),
638                             /*noupdate */ std::string("----") +
639                                 std::string(99, '*') + std::string("--------"),
640                             /*present  */ std::string("a-b-") +
641                                 std::string(99, '-') + std::string("c--D---E"),
642                         },
643                         {});
644   jank_reporter.ReportJankMetrics(100u);
645
646   // One sample of 2 janks reported for "Compositor".
647   const char* metric =
648       "Graphics.Smoothness.Jank.Compositor.CompositorAnimation";
649   const char* invalid_metric =
650       "Graphics.Smoothness.Jank.Main.CompositorAnimation";
651
652   histogram_tester.ExpectTotalCount(metric, 1u);
653   EXPECT_THAT(histogram_tester.GetAllSamples(metric),
654               testing::ElementsAre(base::Bucket(2, 1)));
655
656   // Test all-sequence metrics.
657   histogram_tester.ExpectTotalCount(kAllSequencesMetricName, 1u);
658   EXPECT_THAT(histogram_tester.GetAllSamples(kAllSequencesMetricName),
659               testing::ElementsAre(base::Bucket(2, 1)));
660
661   histogram_tester.ExpectTotalCount(kAllAnimationsMetricName, 1u);
662   EXPECT_THAT(histogram_tester.GetAllSamples(kAllSequencesMetricName),
663               testing::ElementsAre(base::Bucket(2, 1)));
664
665   histogram_tester.ExpectTotalCount(kAllInteractionsMetricName, 0u);
666
667   // Stale-frame metrics
668   const char* stale_metric = "Graphics.Smoothness.Stale.CompositorAnimation";
669   const char* maxstale_metric =
670       "Graphics.Smoothness.MaxStale.CompositorAnimation";
671
672   histogram_tester.ExpectTotalCount(stale_metric, 4u);
673   EXPECT_THAT(histogram_tester.GetAllSamples(stale_metric),
674               testing::ElementsAre(base::Bucket(16, 2), /* a-b & b-c */
675                                    base::Bucket(33, 1), /* c--d */
676                                    base::Bucket(50, 1)) /* d---E */);
677   histogram_tester.ExpectTotalCount(maxstale_metric, 1u);
678   EXPECT_THAT(histogram_tester.GetAllSamples(maxstale_metric),
679               testing::ElementsAre(base::Bucket(50, 1)));
680
681   // No reporting for "Main".
682   histogram_tester.ExpectTotalCount(invalid_metric, 0u);
683 }
684
685 }  // namespace cc