[M108 Migration][VD] Avoid pending frame counter becoming negative
[platform/framework/web/chromium-efl.git] / cc / metrics / event_metrics.h
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 #ifndef CC_METRICS_EVENT_METRICS_H_
6 #define CC_METRICS_EVENT_METRICS_H_
7
8 #include <memory>
9 #include <string>
10 #include <vector>
11
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"
19
20 namespace cc {
21 class PinchEventMetrics;
22 class ScrollEventMetrics;
23 class ScrollUpdateEventMetrics;
24
25 // Data about an event used by CompositorFrameReporter in generating event
26 // latency metrics.
27 class CC_EXPORT EventMetrics {
28  public:
29   using List = std::vector<std::unique_ptr<EventMetrics>>;
30
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 {
34     kMousePressed,
35     kMouseReleased,
36     kMouseWheel,
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.
40     kKeyPressed,
41     kKeyReleased,
42     kTouchPressed,
43     kTouchReleased,
44     kTouchMoved,
45     kGestureScrollBegin,
46     kGestureScrollUpdate,
47     kGestureScrollEnd,
48     kGestureDoubleTap,
49     kGestureLongPress,
50     kGestureLongTap,
51     kGestureShowPress,
52     kGestureTap,
53     kGestureTapCancel,
54     kGestureTapDown,
55     kGestureTapUnconfirmed,
56     kGestureTwoFingerTap,
57     kFirstGestureScrollUpdate,
58     kMouseDragged,
59     kGesturePinchBegin,
60     kGesturePinchEnd,
61     kGesturePinchUpdate,
62     kInertialGestureScrollUpdate,
63     kMaxValue = kInertialGestureScrollUpdate,
64   };
65
66   // Stages of event dispatch in different processes/threads.
67   enum class DispatchStage {
68     kGenerated,
69     kArrivedInBrowserMain,
70     kArrivedInRendererCompositor,
71     kRendererCompositorStarted,
72     kRendererCompositorFinished,
73     kRendererMainStarted,
74     kRendererMainFinished,
75     kMaxValue = kRendererMainFinished,
76   };
77
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);
83
84   // Similar to `Create()` with an extra `base::TickClock` to use in tests.
85   static std::unique_ptr<EventMetrics> CreateForTesting(
86       ui::EventType type,
87       base::TimeTicks timestamp,
88       const base::TickClock* tick_clock);
89
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(
98       ui::EventType type,
99       DispatchStage last_dispatch_stage,
100       const EventMetrics* existing);
101
102   virtual ~EventMetrics();
103
104   EventMetrics& operator=(const EventMetrics&) = delete;
105
106   EventType type() const { return type_; }
107
108   // Returns a string representing event type.
109   const char* GetTypeName() const;
110
111   void SetHighLatencyStage(const std::string& stage);
112   const std::vector<std::string>& GetHighLatencyStages() const {
113     return high_latency_stages_;
114   }
115   void ClearHighLatencyStagesForTesting() { high_latency_stages_.clear(); }
116
117   void SetDispatchStageTimestamp(DispatchStage stage);
118   base::TimeTicks GetDispatchStageTimestamp(DispatchStage stage) const;
119
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);
123
124   bool HasSmoothInputEvent() const;
125
126   virtual ScrollEventMetrics* AsScroll();
127   const ScrollEventMetrics* AsScroll() const;
128
129   virtual ScrollUpdateEventMetrics* AsScrollUpdate();
130   const ScrollUpdateEventMetrics* AsScrollUpdate() const;
131
132   virtual PinchEventMetrics* AsPinch();
133   const PinchEventMetrics* AsPinch() const;
134
135   virtual std::unique_ptr<EventMetrics> Clone() const;
136
137   bool should_record_tracing() const { return should_record_tracing_; }
138   void tracing_recorded() {
139     DCHECK(should_record_tracing_);
140     should_record_tracing_ = false;
141   }
142
143   bool requires_main_thread_update() const {
144     return requires_main_thread_update_;
145   }
146   void set_requires_main_thread_update() {
147     DCHECK(!requires_main_thread_update_);
148     requires_main_thread_update_ = true;
149   }
150
151  protected:
152   EventMetrics(EventType type,
153                base::TimeTicks timestamp,
154                const base::TickClock* tick_clock);
155
156   EventMetrics(EventType type,
157                base::TimeTicks timestamp,
158                base::TimeTicks arrived_in_browser_main_timestamp,
159                const base::TickClock* tick_clock);
160
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
164   // events.
165   EventMetrics(const EventMetrics& other);
166
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);
171
172  private:
173   friend class ScrollEventMetrics;
174   friend class ScrollUpdateEventMetrics;
175
176   static std::unique_ptr<EventMetrics> CreateInternal(
177       ui::EventType type,
178       base::TimeTicks timestamp,
179       const base::TickClock* tick_clock);
180
181   EventType type_;
182
183   std::vector<std::string> high_latency_stages_;
184
185   const raw_ptr<const base::TickClock> tick_clock_;
186
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.
190   base::TimeTicks
191       dispatch_stage_timestamps_[static_cast<int>(DispatchStage::kMaxValue) +
192                                  1];
193
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;
199
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;
205 };
206
207 class CC_EXPORT ScrollEventMetrics : public EventMetrics {
208  public:
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 {
212     kAutoscroll,
213     kScrollbar,
214     kTouchscreen,
215     kWheel,
216     kMaxValue = kWheel,
217   };
218
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.
222   //
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(
226       ui::EventType type,
227       ui::ScrollInputType input_type,
228       bool is_inertial,
229       base::TimeTicks timestamp,
230       base::TimeTicks arrived_in_browser_main_timestamp);
231
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(
236       ui::EventType type,
237       ui::ScrollInputType input_type,
238       bool is_inertial,
239       base::TimeTicks timestamp);
240
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(
244       ui::EventType type,
245       ui::ScrollInputType input_type,
246       bool is_inertial,
247       base::TimeTicks timestamp,
248       base::TimeTicks arrived_in_browser_main_timestamp,
249       const base::TickClock* tick_clock);
250
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(
259       ui::EventType type,
260       ui::ScrollInputType input_type,
261       bool is_inertial,
262       DispatchStage last_dispatch_stage,
263       const EventMetrics* existing);
264
265   ~ScrollEventMetrics() override;
266
267   ScrollType scroll_type() const { return scroll_type_; }
268
269   // Returns a string representing input type for a scroll event.
270   const char* GetScrollTypeName() const;
271
272   ScrollEventMetrics* AsScroll() override;
273
274   std::unique_ptr<EventMetrics> Clone() const override;
275
276  protected:
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&);
283
284  private:
285   static std::unique_ptr<ScrollEventMetrics> CreateInternal(
286       ui::EventType type,
287       ui::ScrollInputType input_type,
288       bool is_inertial,
289       base::TimeTicks timestamp,
290       base::TimeTicks arrived_in_browser_main_timestamp,
291       const base::TickClock* tick_clock);
292
293   // Type of the input device for the event.
294   ScrollType scroll_type_;
295 };
296
297 class CC_EXPORT ScrollUpdateEventMetrics : public ScrollEventMetrics {
298  public:
299   // Determines whether a scroll-update event is the first one in a gesture
300   // scroll sequence or not.
301   enum class ScrollUpdateType {
302     kStarted,
303     kContinued,
304     kMaxValue = kContinued,
305   };
306
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.
309   //
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(
313       ui::EventType type,
314       ui::ScrollInputType input_type,
315       bool is_inertial,
316       ScrollUpdateType scroll_update_type,
317       float delta,
318       base::TimeTicks timestamp,
319       base::TimeTicks arrived_in_browser_main_timestamp);
320
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(
325       ui::EventType type,
326       ui::ScrollInputType input_type,
327       bool is_inertial,
328       ScrollUpdateType scroll_update_type,
329       float delta,
330       base::TimeTicks timestamp);
331
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(
335       ui::EventType type,
336       ui::ScrollInputType input_type,
337       bool is_inertial,
338       ScrollUpdateType scroll_update_type,
339       float delta,
340       base::TimeTicks timestamp,
341       base::TimeTicks arrived_in_browser_main_timestamp,
342       const base::TickClock* tick_clock);
343
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(
352       ui::EventType type,
353       ui::ScrollInputType input_type,
354       bool is_inertial,
355       ScrollUpdateType scroll_update_type,
356       float delta,
357       DispatchStage last_dispatch_stage,
358       const EventMetrics* existing);
359
360   ~ScrollUpdateEventMetrics() override;
361
362   void CoalesceWith(const ScrollUpdateEventMetrics& newer_scroll_update);
363
364   ScrollUpdateEventMetrics* AsScrollUpdate() override;
365
366   float delta() const { return delta_; }
367
368   float predicted_delta() const { return predicted_delta_; }
369   void set_predicted_delta(float predicted_delta) {
370     predicted_delta_ = predicted_delta;
371   }
372
373   base::TimeTicks last_timestamp() const { return last_timestamp_; }
374
375   std::unique_ptr<EventMetrics> Clone() const override;
376
377  protected:
378   ScrollUpdateEventMetrics(EventType type,
379                            ScrollType scroll_type,
380                            ScrollUpdateType scroll_update_type,
381                            float delta,
382                            base::TimeTicks timestamp,
383                            base::TimeTicks arrived_in_browser_main_timestamp,
384                            const base::TickClock* tick_clock);
385   ScrollUpdateEventMetrics(const ScrollUpdateEventMetrics&);
386
387  private:
388   static std::unique_ptr<ScrollUpdateEventMetrics> CreateInternal(
389       ui::EventType type,
390       ui::ScrollInputType input_type,
391       bool is_inertial,
392       ScrollUpdateType scroll_update_type,
393       float delta,
394       base::TimeTicks timestamp,
395       base::TimeTicks arrived_in_browser_main_timestamp,
396       const base::TickClock* tick_clock);
397
398   float delta_;
399   float predicted_delta_;
400
401   // Timestamp of the last event coalesced into this one.
402   base::TimeTicks last_timestamp_;
403 };
404
405 class CC_EXPORT PinchEventMetrics : public EventMetrics {
406  public:
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 {
410     kTouchpad,
411     kTouchscreen,
412     kMaxValue = kTouchscreen,
413   };
414
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(
418       ui::EventType type,
419       ui::ScrollInputType input_type,
420       base::TimeTicks timestamp);
421
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(
425       ui::EventType type,
426       ui::ScrollInputType input_type,
427       base::TimeTicks timestamp,
428       const base::TickClock* tick_clock);
429
430   ~PinchEventMetrics() override;
431
432   PinchType pinch_type() const { return pinch_type_; }
433
434   // Returns a string representing input type for a pinch event. Should only be
435   // called for pinch events.
436   const char* GetPinchTypeName() const;
437
438   PinchEventMetrics* AsPinch() override;
439
440   std::unique_ptr<EventMetrics> Clone() const override;
441
442  protected:
443   PinchEventMetrics(EventType type,
444                     PinchType pinch_type,
445                     base::TimeTicks timestamp,
446                     const base::TickClock* tick_clock);
447   PinchEventMetrics(const PinchEventMetrics&);
448
449  private:
450   static std::unique_ptr<PinchEventMetrics> CreateInternal(
451       ui::EventType type,
452       ui::ScrollInputType input_type,
453       base::TimeTicks timestamp,
454       const base::TickClock* tick_clock);
455
456   PinchType pinch_type_;
457 };
458
459 // Struct storing event metrics from both main and impl threads.
460 struct CC_EXPORT EventMetricsSet {
461   EventMetricsSet();
462   ~EventMetricsSet();
463   EventMetricsSet(EventMetrics::List main_thread_event_metrics,
464                   EventMetrics::List impl_thread_event_metrics);
465   EventMetricsSet(EventMetricsSet&&);
466   EventMetricsSet& operator=(EventMetricsSet&&);
467
468   EventMetricsSet(const EventMetricsSet&) = delete;
469   EventMetricsSet& operator=(const EventMetricsSet&) = delete;
470
471   EventMetrics::List main_event_metrics;
472   EventMetrics::List impl_event_metrics;
473 };
474
475 }  // namespace cc
476
477 #endif  // CC_METRICS_EVENT_METRICS_H_