summaryrefslogtreecommitdiff
path: root/chromium/ui/latency/latency_tracker.h
blob: 24397fc4ba6d3e752030995cdc7481a0e7ad1824 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef UI_LATENCY_LATENCY_TRACKER_H_
#define UI_LATENCY_LATENCY_TRACKER_H_

#include "base/macros.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
#include "ui/latency/latency_info.h"

namespace ui {

// Utility class for tracking the latency of events. Relies on LatencyInfo
// components logged by content::RenderWidgetHostLatencyTracker.
class LatencyTracker {
 public:
  explicit LatencyTracker(bool metric_sampling,
                          ukm::SourceId ukm_source_id = ukm::kInvalidSourceId);
  ~LatencyTracker() = default;

  void OnEventStart(LatencyInfo* latency);

  // Terminates latency tracking for events that triggered rendering, also
  // performing relevant UMA latency reporting.
  // Called when GPU buffers swap completes.
  void OnGpuSwapBuffersCompleted(const LatencyInfo& latency);

 protected:
  ukm::SourceId ukm_source_id() const { return ukm_source_id_; }

 private:
  enum class InputMetricEvent {
    SCROLL_BEGIN_TOUCH = 0,
    SCROLL_UPDATE_TOUCH,
    SCROLL_BEGIN_WHEEL,
    SCROLL_UPDATE_WHEEL,

    INPUT_METRIC_EVENT_MAX = SCROLL_UPDATE_WHEEL
  };

  void ReportUkmScrollLatency(
      const InputMetricEvent& metric_event,
      const LatencyInfo::LatencyComponent& start_component,
      const LatencyInfo::LatencyComponent&
          time_to_scroll_update_swap_begin_component,
      const LatencyInfo::LatencyComponent& time_to_handled_component,
      bool is_main_thread,
      const ukm::SourceId ukm_source_id);

  void ComputeEndToEndLatencyHistograms(
      const LatencyInfo::LatencyComponent& gpu_swap_begin_component,
      const LatencyInfo::LatencyComponent& gpu_swap_end_component,
      const LatencyInfo& latency);

  typedef struct SamplingScheme {
    SamplingScheme() : interval_(1), last_sample_(0) {}
    SamplingScheme(int interval)
        : interval_(interval), last_sample_(rand() % interval) {}
    bool ShouldReport() {
      last_sample_++;
      last_sample_ %= interval_;
      return last_sample_ == 0;
    }

   private:
    int interval_;
    int last_sample_;
  } SamplingScheme;

  // Whether the sampling is needed for high volume metrics. This will be off
  // when we are in unit tests. This is a temporary field so we can come up with
  // a more permanent solution for crbug.com/739169.
  bool metric_sampling_;
  // The i'th member of this array stores the sampling rate for the i'th
  // input metric event type. Initializing SamplingScheme with number X means
  // that from every X events one will be reported. Note that the first event
  // to report is also randomized.
  SamplingScheme sampling_scheme_
      [static_cast<int>(InputMetricEvent::INPUT_METRIC_EVENT_MAX) + 1] = {
          SamplingScheme(5),   // SCROLL_BEGIN_TOUCH
          SamplingScheme(50),  // SCROLL_UPDATE_TOUCH
          SamplingScheme(5),   // SCROLL_BEGIN_WHEEL
          SamplingScheme(2),   // SCROLL_UPDATE_WHEEL
  };
  const ukm::SourceId ukm_source_id_;

  DISALLOW_COPY_AND_ASSIGN(LatencyTracker);
};

}  // namespace latency

#endif  // UI_LATENCY_LATENCY_TRACKER_H_