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.
5 #ifndef CC_METRICS_EVENT_METRICS_H_
6 #define CC_METRICS_EVENT_METRICS_H_
12 #include "base/memory/raw_ptr.h"
13 #include "base/time/tick_clock.h"
14 #include "base/time/time.h"
15 #include "cc/cc_export.h"
16 #include "third_party/abseil-cpp/absl/types/optional.h"
17 #include "ui/events/types/event_type.h"
18 #include "ui/events/types/scroll_input_type.h"
21 class PinchEventMetrics;
22 class ScrollEventMetrics;
23 class ScrollUpdateEventMetrics;
25 // Data about an event used by CompositorFrameReporter in generating event
27 class CC_EXPORT EventMetrics {
29 using List = std::vector<std::unique_ptr<EventMetrics>>;
31 // Event types we are interested in. This list should be in the same order as
32 // values of EventLatencyEventType enum from enums.xml file.
33 enum class EventType {
37 // TODO(crbug/1071645): Currently, all ET_KEY_PRESSED events are reported
38 // under EventLatency.KeyPressed histogram. This includes both key-down and
39 // key-char events. Consider reporting them separately.
55 kGestureTapUnconfirmed,
57 kFirstGestureScrollUpdate,
62 kInertialGestureScrollUpdate,
63 kMaxValue = kInertialGestureScrollUpdate,
66 // Stages of event dispatch in different processes/threads.
67 enum class DispatchStage {
69 kArrivedInBrowserMain,
70 kArrivedInRendererCompositor,
71 kRendererCompositorStarted,
72 kRendererCompositorFinished,
74 kRendererMainFinished,
75 kMaxValue = kRendererMainFinished,
78 // Returns a new instance if the event is of a type we are interested in.
79 // Otherwise, returns `nullptr`. For scroll and pinch events, use the
80 // appropriate subcalss instead.
81 static std::unique_ptr<EventMetrics> Create(ui::EventType type,
82 base::TimeTicks timestamp);
84 // Similar to `Create()` with an extra `base::TickClock` to use in tests.
85 static std::unique_ptr<EventMetrics> CreateForTesting(
87 base::TimeTicks timestamp,
88 const base::TickClock* tick_clock);
90 // Used to create an instance for an event generated based on an existing
91 // event. If the new event is of an interesting type, we expect that the
92 // existing event is also of an interesting type in which case `existing` is
93 // not `nullptr` and timestamps (up to and including `last_dispatch_stage`)
94 // and tick clock from `existing` will be used for the new metrics object. If
95 // the new event is not an interesting one, return value would be `nullptr`.
96 // For scroll and pinch events, use the appropriate subclass instead.
97 static std::unique_ptr<EventMetrics> CreateFromExisting(
99 DispatchStage last_dispatch_stage,
100 const EventMetrics* existing);
102 virtual ~EventMetrics();
104 EventMetrics& operator=(const EventMetrics&) = delete;
106 EventType type() const { return type_; }
108 // Returns a string representing event type.
109 const char* GetTypeName() const;
111 void SetHighLatencyStage(const std::string& stage);
112 const std::vector<std::string>& GetHighLatencyStages() const {
113 return high_latency_stages_;
115 void ClearHighLatencyStagesForTesting() { high_latency_stages_.clear(); }
117 void SetDispatchStageTimestamp(DispatchStage stage);
118 base::TimeTicks GetDispatchStageTimestamp(DispatchStage stage) const;
120 // Resets the metrics object to dispatch stage `stage` by setting timestamps
121 // of dispatch stages after `stage` to null timestamp,
122 void ResetToDispatchStage(DispatchStage stage);
124 bool HasSmoothInputEvent() const;
126 virtual ScrollEventMetrics* AsScroll();
127 const ScrollEventMetrics* AsScroll() const;
129 virtual ScrollUpdateEventMetrics* AsScrollUpdate();
130 const ScrollUpdateEventMetrics* AsScrollUpdate() const;
132 virtual PinchEventMetrics* AsPinch();
133 const PinchEventMetrics* AsPinch() const;
135 virtual std::unique_ptr<EventMetrics> Clone() const;
137 bool should_record_tracing() const { return should_record_tracing_; }
138 void tracing_recorded() {
139 DCHECK(should_record_tracing_);
140 should_record_tracing_ = false;
143 bool requires_main_thread_update() const {
144 return requires_main_thread_update_;
146 void set_requires_main_thread_update() {
147 DCHECK(!requires_main_thread_update_);
148 requires_main_thread_update_ = true;
152 EventMetrics(EventType type,
153 base::TimeTicks timestamp,
154 const base::TickClock* tick_clock);
156 EventMetrics(EventType type,
157 base::TimeTicks timestamp,
158 base::TimeTicks arrived_in_browser_main_timestamp,
159 const base::TickClock* tick_clock);
161 // Creates a clone of `other` that might be used in creating `EventMetrics`
162 // objects for some injected events. Since this object itself does not
163 // directly correspond to an event, it won't be used in recording trace
165 EventMetrics(const EventMetrics& other);
167 // Copy timestamps of dispatch stages (up to and including
168 // `last_dispatch_stage`) from `other`.
169 void CopyTimestampsFrom(const EventMetrics& other,
170 DispatchStage last_dispatch_stage);
173 friend class ScrollEventMetrics;
174 friend class ScrollUpdateEventMetrics;
176 static std::unique_ptr<EventMetrics> CreateInternal(
178 base::TimeTicks timestamp,
179 const base::TickClock* tick_clock);
183 std::vector<std::string> high_latency_stages_;
185 const raw_ptr<const base::TickClock> tick_clock_;
187 // Timestamps of different stages of event dispatch. Timestamps are set as the
188 // event moves forward in the pipeline. In the end, some stages might not have
189 // a timestamp which means the event did not pass those stages.
191 dispatch_stage_timestamps_[static_cast<int>(DispatchStage::kMaxValue) +
194 // Determines whether a tracing event should be recorded for this object or
195 // not. This is `true` by default and set to `false` after a tracing event is
196 // recorded to avoid multiple recordings. Also, it is `false` for cloned
197 // objects as they are not meant to be recorded in tracings.
198 bool should_record_tracing_ = true;
200 // This is set on an EventMetrics object that comes from the impl thread, if
201 // the visual update from the event requires the main thread. Currently used
202 // for GestureScrollUpdate with scroll unification, when the scroller isn't
203 // composited or has main-thread scrolling reasons on the ScrollNode.
204 bool requires_main_thread_update_ = false;
207 class CC_EXPORT ScrollEventMetrics : public EventMetrics {
209 // Type of scroll events. This list should be in the same order as values of
210 // `EventLatencyScrollInputType` enum from enums.xml file.
211 enum class ScrollType {
219 // Returns a new instance if the event is of a type we are interested in.
220 // Otherwise, returns `nullptr`. Should only be used for scroll events other
221 // than scroll-update.
223 // TODO(b/224960731): Fix tests and stop supporting the case when
224 // `arrived_in_browser_main_timestamp` is null.
225 static std::unique_ptr<ScrollEventMetrics> Create(
227 ui::ScrollInputType input_type,
229 base::TimeTicks timestamp,
230 base::TimeTicks arrived_in_browser_main_timestamp);
232 // Prefer to use `Create()` above. This method is used only by the Browser
233 // process which have own breakdowns.
234 // Similar to `Create()` above but doesn't set kArrivedInBrowserMain.
235 static std::unique_ptr<ScrollEventMetrics> CreateForBrowser(
237 ui::ScrollInputType input_type,
239 base::TimeTicks timestamp);
241 // Similar to `Create()` with an extra `base::TickClock` to use in tests.
242 // Should only be used for scroll events other than scroll-update.
243 static std::unique_ptr<ScrollEventMetrics> CreateForTesting(
245 ui::ScrollInputType input_type,
247 base::TimeTicks timestamp,
248 base::TimeTicks arrived_in_browser_main_timestamp,
249 const base::TickClock* tick_clock);
251 // Used to create an instance for an event generated based on an existing
252 // event. If the new event is of an interesting type, we expect that the
253 // existing event is also of an interesting type in which case `existing` is
254 // not `nullptr` and timestamps (up to and including `last_dispatch_stage`)
255 // and tick clock from `existing` will be used for the new metrics object. If
256 // the new event is not an interesting one, return value would be `nullptr`.
257 // Should only be used for scroll events other than scroll-update.
258 static std::unique_ptr<ScrollEventMetrics> CreateFromExisting(
260 ui::ScrollInputType input_type,
262 DispatchStage last_dispatch_stage,
263 const EventMetrics* existing);
265 ~ScrollEventMetrics() override;
267 ScrollType scroll_type() const { return scroll_type_; }
269 // Returns a string representing input type for a scroll event.
270 const char* GetScrollTypeName() const;
272 ScrollEventMetrics* AsScroll() override;
274 std::unique_ptr<EventMetrics> Clone() const override;
277 ScrollEventMetrics(EventType type,
278 ScrollType scroll_type,
279 base::TimeTicks timestamp,
280 base::TimeTicks arrived_in_browser_main_timestamp,
281 const base::TickClock* tick_clock);
282 ScrollEventMetrics(const ScrollEventMetrics&);
285 static std::unique_ptr<ScrollEventMetrics> CreateInternal(
287 ui::ScrollInputType input_type,
289 base::TimeTicks timestamp,
290 base::TimeTicks arrived_in_browser_main_timestamp,
291 const base::TickClock* tick_clock);
293 // Type of the input device for the event.
294 ScrollType scroll_type_;
297 class CC_EXPORT ScrollUpdateEventMetrics : public ScrollEventMetrics {
299 // Determines whether a scroll-update event is the first one in a gesture
300 // scroll sequence or not.
301 enum class ScrollUpdateType {
304 kMaxValue = kContinued,
307 // Returns a new instance if the event is of a type we are interested in.
308 // Otherwise, returns `nullptr`. Should only be used for scroll-update events.
310 // TODO(b/224960731): Fix tests and stop supporting the case when
311 // `arrived_in_browser_main_timestamp` is null.
312 static std::unique_ptr<ScrollUpdateEventMetrics> Create(
314 ui::ScrollInputType input_type,
316 ScrollUpdateType scroll_update_type,
318 base::TimeTicks timestamp,
319 base::TimeTicks arrived_in_browser_main_timestamp);
321 // Prefer to use `Create()` above. This method is used only by the Browser
322 // process which have own breakdowns.
323 // Similar to `Create()` above but doesn't set kArrivedInBrowserMain.
324 static std::unique_ptr<ScrollUpdateEventMetrics> CreateForBrowser(
326 ui::ScrollInputType input_type,
328 ScrollUpdateType scroll_update_type,
330 base::TimeTicks timestamp);
332 // Similar to `Create()` with an extra `base::TickClock` to use in tests.
333 // Should only be used for scroll-update events.
334 static std::unique_ptr<ScrollUpdateEventMetrics> CreateForTesting(
336 ui::ScrollInputType input_type,
338 ScrollUpdateType scroll_update_type,
340 base::TimeTicks timestamp,
341 base::TimeTicks arrived_in_browser_main_timestamp,
342 const base::TickClock* tick_clock);
344 // Used to create an instance for an event generated based on an existing
345 // event. If the new event is of an interesting type, we expect that the
346 // existing event is also of an interesting type in which case `existing` is
347 // not `nullptr` and timestamps (up to and including `last_dispatch_stage`)
348 // and tick clock from `existing` will be used for the new metrics object. If
349 // the new event is not an interesting one, return value would be `nullptr`.
350 // Should only be used for scroll-update events.
351 static std::unique_ptr<ScrollUpdateEventMetrics> CreateFromExisting(
353 ui::ScrollInputType input_type,
355 ScrollUpdateType scroll_update_type,
357 DispatchStage last_dispatch_stage,
358 const EventMetrics* existing);
360 ~ScrollUpdateEventMetrics() override;
362 void CoalesceWith(const ScrollUpdateEventMetrics& newer_scroll_update);
364 ScrollUpdateEventMetrics* AsScrollUpdate() override;
366 float delta() const { return delta_; }
368 float predicted_delta() const { return predicted_delta_; }
369 void set_predicted_delta(float predicted_delta) {
370 predicted_delta_ = predicted_delta;
373 base::TimeTicks last_timestamp() const { return last_timestamp_; }
375 std::unique_ptr<EventMetrics> Clone() const override;
378 ScrollUpdateEventMetrics(EventType type,
379 ScrollType scroll_type,
380 ScrollUpdateType scroll_update_type,
382 base::TimeTicks timestamp,
383 base::TimeTicks arrived_in_browser_main_timestamp,
384 const base::TickClock* tick_clock);
385 ScrollUpdateEventMetrics(const ScrollUpdateEventMetrics&);
388 static std::unique_ptr<ScrollUpdateEventMetrics> CreateInternal(
390 ui::ScrollInputType input_type,
392 ScrollUpdateType scroll_update_type,
394 base::TimeTicks timestamp,
395 base::TimeTicks arrived_in_browser_main_timestamp,
396 const base::TickClock* tick_clock);
399 float predicted_delta_;
401 // Timestamp of the last event coalesced into this one.
402 base::TimeTicks last_timestamp_;
405 class CC_EXPORT PinchEventMetrics : public EventMetrics {
407 // Type of pinch events. This list should be in the same order as values of
408 // `EventLatencyPinchInputType` enum from enums.xml file.
409 enum class PinchType {
412 kMaxValue = kTouchscreen,
415 // Returns a new instance if the event is of a type we are interested in.
416 // Otherwise, returns `nullptr`. Should only be used for pinch events.
417 static std::unique_ptr<PinchEventMetrics> Create(
419 ui::ScrollInputType input_type,
420 base::TimeTicks timestamp);
422 // Similar to `Create()` with an extra `base::TickClock` to use in tests.
423 // Should only be used for pinch events.
424 static std::unique_ptr<PinchEventMetrics> CreateForTesting(
426 ui::ScrollInputType input_type,
427 base::TimeTicks timestamp,
428 const base::TickClock* tick_clock);
430 ~PinchEventMetrics() override;
432 PinchType pinch_type() const { return pinch_type_; }
434 // Returns a string representing input type for a pinch event. Should only be
435 // called for pinch events.
436 const char* GetPinchTypeName() const;
438 PinchEventMetrics* AsPinch() override;
440 std::unique_ptr<EventMetrics> Clone() const override;
443 PinchEventMetrics(EventType type,
444 PinchType pinch_type,
445 base::TimeTicks timestamp,
446 const base::TickClock* tick_clock);
447 PinchEventMetrics(const PinchEventMetrics&);
450 static std::unique_ptr<PinchEventMetrics> CreateInternal(
452 ui::ScrollInputType input_type,
453 base::TimeTicks timestamp,
454 const base::TickClock* tick_clock);
456 PinchType pinch_type_;
459 // Struct storing event metrics from both main and impl threads.
460 struct CC_EXPORT EventMetricsSet {
463 EventMetricsSet(EventMetrics::List main_thread_event_metrics,
464 EventMetrics::List impl_thread_event_metrics);
465 EventMetricsSet(EventMetricsSet&&);
466 EventMetricsSet& operator=(EventMetricsSet&&);
468 EventMetricsSet(const EventMetricsSet&) = delete;
469 EventMetricsSet& operator=(const EventMetricsSet&) = delete;
471 EventMetrics::List main_event_metrics;
472 EventMetrics::List impl_event_metrics;
477 #endif // CC_METRICS_EVENT_METRICS_H_