File: latency_info.h

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (223 lines) | stat: -rw-r--r-- 9,613 bytes parent folder | download | duplicates (5)
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef UI_LATENCY_LATENCY_INFO_H_
#define UI_LATENCY_LATENCY_INFO_H_

#include <optional>
#include <vector>

#include "base/containers/flat_map.h"
#include "base/time/time.h"
#include "build/blink_buildflags.h"
#include "build/build_config.h"

#if BUILDFLAG(USE_BLINK)
#include "ipc/ipc_param_traits.h"  // nogncheck
#include "mojo/public/cpp/bindings/struct_traits.h"  // nogncheck
#endif

namespace perfetto {
class EventContext;

// These enums are somewhat arduous to forward-declare, but it's worth it
// because the header which defines them is enormous and this header is widely
// used.
namespace protos::pbzero {
namespace perfetto_pbzero_enum_ChromeLatencyInfo2 {
enum InputResultState : int32_t;
enum InputType : int32_t;
enum Step : int32_t;
}  // namespace perfetto_pbzero_enum_ChromeLatencyInfo2
class ChromeLatencyInfo2;
using ChromeLatencyInfo2_InputResultState =
    perfetto_pbzero_enum_ChromeLatencyInfo2::InputResultState;
using ChromeLatencyInfo2_InputType =
    perfetto_pbzero_enum_ChromeLatencyInfo2::InputType;
using ChromeLatencyInfo2_Step = perfetto_pbzero_enum_ChromeLatencyInfo2::Step;
}  // namespace protos::pbzero
}  // namespace perfetto

namespace ui {

#if BUILDFLAG(USE_BLINK)
namespace mojom {
class LatencyInfoDataView;
}
#endif

// When adding new components, or new metrics based on LatencyInfo,
// please update latency_info.dot.
//
// When adding new components, please update
// //third_party/perfetto/protos/perfetto/trace/track_event/chrome_latency_info.proto
// so both this and the internal versions can be kept up to date. Or reach out
// to tracing@chromium.org so we can assist.
enum LatencyComponentType {
  // ---------------------------BEGIN COMPONENT-------------------------------
  // BEGIN COMPONENT is when we show the latency begin in chrome://tracing.
  // Timestamp when the input event is sent from RenderWidgetHost to renderer.
  INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
  // ---------------------------NORMAL COMPONENT-------------------------------
  // The original timestamp of the touch event which converts to scroll update.
  INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT,
  // The original timestamp of the touch event which converts to the *first*
  // scroll update in a scroll gesture sequence.
  INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL_COMPONENT,
  // Original timestamp for input event (e.g. timestamp from kernel).
  INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT,
  // Timestamp when the UI event is created.
  INPUT_EVENT_LATENCY_UI_COMPONENT,
  // Timestamp when the event is dispatched on the main thread of the renderer.
  INPUT_EVENT_LATENCY_RENDERER_MAIN_COMPONENT,
  // This is special component indicating there is rendering scheduled for
  // the event associated with this LatencyInfo on main thread.
  INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_MAIN_COMPONENT,
  // This is special component indicating there is rendering scheduled for
  // the event associated with this LatencyInfo on impl thread.
  INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_IMPL_COMPONENT,
  // Timestamp when the frame is swapped in renderer.
  INPUT_EVENT_LATENCY_RENDERER_SWAP_COMPONENT,
  // Timestamp of when the display compositor receives a compositor frame from
  // the renderer.
  // Display compositor can be either in the browser process or in Mus.
  DISPLAY_COMPOSITOR_RECEIVED_FRAME_COMPONENT,
  // Timestamp of when the gpu service began swap buffers, unlike
  // INPUT_EVENT_LATENCY_FRAME_SWAP_COMPONENT which measures after.
  INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT,
  // Timestamp when the frame is swapped (i.e. when the rendering caused by
  // input event actually takes effect).
  INPUT_EVENT_LATENCY_FRAME_SWAP_COMPONENT,

  LATENCY_COMPONENT_TYPE_LAST = INPUT_EVENT_LATENCY_FRAME_SWAP_COMPONENT,
};

class LatencyInfo {
 public:
  // Map a Latency Component (with a component-specific int64_t id) to a
  // timestamp.
  using LatencyMap = base::flat_map<LatencyComponentType, base::TimeTicks>;

  LatencyInfo();
  LatencyInfo(const LatencyInfo& other);
  LatencyInfo(LatencyInfo&& other);
  ~LatencyInfo();

  // For test only.
  LatencyInfo(int64_t trace_id, bool terminated);

  LatencyInfo& operator=(const LatencyInfo& other);

  // Returns true if the vector |latency_info| is valid. Returns false
  // if it is not valid and log the |referring_msg|.
  // This function is mainly used to check the latency_info vector that
  // is passed between processes using IPC message has reasonable size
  // so that we are confident the IPC message is not corrupted/compromised.
  // This check will go away once the IPC system has better built-in scheme
  // for corruption/compromise detection.
  static bool Verify(const std::vector<LatencyInfo>& latency_info,
                     const char* referring_msg);

  // Populates fields for the `LatencyInfo.Flow` event in a flow, for
  // `latency_trace_id` with `ctx`. Returns a pointer to the created
  // `ChromeLatencyInfo2` message.
  //
  // NOTE: Due to ProtoZero write semantics, if the caller wants to modify the
  //       returned `ChromeLatencyInfo2`, they should do it immediately after
  //       `FillTraceEvent` returns, and before writes to any other fields or
  //       submessages.
  static perfetto::protos::pbzero::ChromeLatencyInfo2* FillTraceEvent(
      perfetto::EventContext& ctx,
      int64_t latency_trace_id,
      perfetto::protos::pbzero::ChromeLatencyInfo2_Step step,
      std::optional<perfetto::protos::pbzero::ChromeLatencyInfo2_InputType>
          input_type = std::nullopt,
      std::optional<
          perfetto::protos::pbzero::ChromeLatencyInfo2_InputResultState>
          input_result_state = std::nullopt);

  // Add timestamps for components that are in |other| but not in |this|.
  void AddNewLatencyFrom(const LatencyInfo& other);

  // Modifies the current sequence number for a component, and adds a new
  // sequence number with the current timestamp.
  void AddLatencyNumber(LatencyComponentType component);

  // Similar to |AddLatencyNumber|, and also appends |trace_name_str| to
  // the trace event's name.
  // This function should only be called when adding a BEGIN component.
  void AddLatencyNumberWithTraceName(LatencyComponentType component,
                                     const char* trace_name_str,
                                     base::TimeTicks now);

  // Modifies the current sequence number and adds a certain number of events
  // for a specific component.
  void AddLatencyNumberWithTimestamp(LatencyComponentType component,
                                     base::TimeTicks time);

  // Returns true if a component with |type| is found in the latency component.
  // The first such component (when iterating over latency_components_) is
  // stored to |output| if |output| is not NULL. Returns false if no such
  // component is found.
  bool FindLatency(LatencyComponentType type, base::TimeTicks* output) const;

  void Terminate();

  const LatencyMap& latency_components() const { return latency_components_; }

  bool began() const { return began_; }
  bool terminated() const { return terminated_; }
  void set_coalesced() { coalesced_ = true; }
  bool coalesced() const { return coalesced_; }
  int64_t trace_id() const { return trace_id_; }
  void set_trace_id(int64_t trace_id) { trace_id_ = trace_id; }
  int64_t gesture_scroll_id() const { return gesture_scroll_id_; }
  void set_gesture_scroll_id(int64_t id) { gesture_scroll_id_ = id; }
  int64_t touch_trace_id() const { return touch_trace_id_; }
  void set_touch_trace_id(int64_t id) { touch_trace_id_ = id; }

 private:
  void AddLatencyNumberWithTimestampImpl(LatencyComponentType component,
                                         base::TimeTicks time,
                                         const char* trace_name_str);

  LatencyMap latency_components_;

  // The unique id for matching the ASYNC_BEGIN/END trace event.
  int64_t trace_id_ = -1;
  // Whether this event has been coalesced into another event.
  bool coalesced_ = false;
  // Whether a begin component has been added.
  bool began_ = false;
  // Whether a terminal component has been added.
  bool terminated_ = false;

  // The unique id for denoting a scroll gesture. This is only set for
  // GestureScrollBegin, GestureScrollUpdate, and GestureScrollEnd events, and
  // allows easy grouping of these global async events into a single logical
  // scroll in the sql interface of TBMv3 (Trace Based Metrics v3). As a current
  // implementation detail this unique id comes from the |trace_id| of the
  // associated GestureScrollBegin (-1 if there was none or it wasn't valid).
  int64_t gesture_scroll_id_ = 0;
  // The unique id for denoting a touch, tracking from TouchStart through
  // TouchMoves to TouchEnd. Used for TBMv3 metrics as in the same way as
  // gesture_scroll_id_.
  int64_t touch_trace_id_ = 0;

#if BUILDFLAG(USE_BLINK)
  friend struct IPC::ParamTraits<ui::LatencyInfo>;
  friend struct mojo::StructTraits<ui::mojom::LatencyInfoDataView,
                                   ui::LatencyInfo>;
#endif
};

// This is declared here for use in gtest-based unit tests, but is defined in
// //ui/latency:test_support target.
// Without this the default PrintTo template in gtest tries to pass LatencyInfo
// by value, which leads to an alignment compile error on Windows.
void PrintTo(const LatencyInfo& latency, ::std::ostream* os);

}  // namespace ui

#endif  // UI_LATENCY_LATENCY_INFO_H_