[M108 Migration][VD] Avoid pending frame counter becoming negative
[platform/framework/web/chromium-efl.git] / cc / metrics / compositor_frame_reporting_controller.h
1 // Copyright 2019 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_COMPOSITOR_FRAME_REPORTING_CONTROLLER_H_
6 #define CC_METRICS_COMPOSITOR_FRAME_REPORTING_CONTROLLER_H_
7
8 #include <map>
9 #include <memory>
10 #include <queue>
11 #include <vector>
12
13 #include "base/memory/raw_ptr.h"
14 #include "base/time/default_tick_clock.h"
15 #include "base/time/time.h"
16 #include "cc/cc_export.h"
17 #include "cc/metrics/compositor_frame_reporter.h"
18 #include "cc/metrics/event_metrics.h"
19 #include "cc/metrics/frame_sequence_metrics.h"
20
21 namespace viz {
22 struct FrameTimingDetails;
23 }
24
25 namespace cc {
26 class DroppedFrameCounter;
27 class EventLatencyTracker;
28 class UkmManager;
29 struct BeginMainFrameMetrics;
30 struct FrameInfo;
31
32 // This is used for managing simultaneous CompositorFrameReporter instances
33 // in the case that the compositor has high latency. Calling one of the
34 // event functions will begin recording the time of the corresponding
35 // phase and trace it. If the frame is eventually submitted, then the
36 // recorded times of each phase will be reported in UMA.
37 // See CompositorFrameReporter.
38 class CC_EXPORT CompositorFrameReportingController {
39  public:
40   // Used as indices for accessing CompositorFrameReporters.
41   enum PipelineStage {
42     kBeginImplFrame = 0,
43     kBeginMainFrame,
44     kReadyToCommit,
45     kCommit,
46     kActivate,
47     kNumPipelineStages
48   };
49
50   CompositorFrameReportingController(bool should_report_histograms,
51                                      bool should_report_ukm,
52                                      int layer_tree_host_id);
53   virtual ~CompositorFrameReportingController();
54
55   CompositorFrameReportingController(
56       const CompositorFrameReportingController&) = delete;
57   CompositorFrameReportingController& operator=(
58       const CompositorFrameReportingController&) = delete;
59
60   // Events to signal Beginning/Ending of phases.
61   virtual void WillBeginImplFrame(const viz::BeginFrameArgs& args);
62   virtual void WillBeginMainFrame(const viz::BeginFrameArgs& args);
63   virtual void BeginMainFrameAborted(const viz::BeginFrameId& id,
64                                      CommitEarlyOutReason reason);
65   virtual void WillInvalidateOnImplSide();
66   virtual void WillCommit();
67   virtual void DidCommit();
68   virtual void WillActivate();
69   virtual void DidActivate();
70   virtual void DidSubmitCompositorFrame(
71       uint32_t frame_token,
72       base::TimeTicks submit_time,
73       const viz::BeginFrameId& current_frame_id,
74       const viz::BeginFrameId& last_activated_frame_id,
75       EventMetricsSet events_metrics,
76       bool has_missing_content);
77   virtual void DidNotProduceFrame(const viz::BeginFrameId& id,
78                                   FrameSkippedReason skip_reason);
79   virtual void OnFinishImplFrame(const viz::BeginFrameId& id);
80   virtual void DidPresentCompositorFrame(
81       uint32_t frame_token,
82       const viz::FrameTimingDetails& details);
83   void OnStoppedRequestingBeginFrames();
84
85   void NotifyReadyToCommit(std::unique_ptr<BeginMainFrameMetrics> details);
86
87   void SetUkmManager(UkmManager* manager);
88
89   void AddActiveTracker(FrameSequenceTrackerType type);
90   void RemoveActiveTracker(FrameSequenceTrackerType type);
91   void SetScrollingThread(FrameInfo::SmoothEffectDrivingThread thread);
92
93   void SetThreadAffectsSmoothness(
94       FrameInfo::SmoothEffectDrivingThread thread_type,
95       bool affects_smoothness);
96   bool is_main_thread_driving_smoothness() const {
97     return is_main_thread_driving_smoothness_;
98   }
99
100   void set_tick_clock(const base::TickClock* tick_clock) {
101     DCHECK(tick_clock);
102     tick_clock_ = tick_clock;
103   }
104
105   std::unique_ptr<CompositorFrameReporter>* reporters() { return reporters_; }
106
107   void SetDroppedFrameCounter(DroppedFrameCounter* counter);
108
109   void SetFrameSequenceTrackerCollection(
110       FrameSequenceTrackerCollection* frame_sequence_trackers) {
111     global_trackers_.frame_sequence_trackers = frame_sequence_trackers;
112   }
113
114   void set_event_latency_tracker(EventLatencyTracker* event_latency_tracker) {
115     global_trackers_.event_latency_tracker = event_latency_tracker;
116   }
117
118   void BeginMainFrameStarted(base::TimeTicks begin_main_frame_start_time) {
119     begin_main_frame_start_time_ = begin_main_frame_start_time;
120   }
121
122   bool HasReporterAt(PipelineStage stage) const;
123
124  protected:
125   struct SubmittedCompositorFrame {
126     uint32_t frame_token;
127     std::unique_ptr<CompositorFrameReporter> reporter;
128     SubmittedCompositorFrame();
129     SubmittedCompositorFrame(uint32_t frame_token,
130                              std::unique_ptr<CompositorFrameReporter> reporter);
131     SubmittedCompositorFrame(SubmittedCompositorFrame&& other);
132     ~SubmittedCompositorFrame();
133   };
134   base::TimeTicks Now() const;
135
136   bool next_activate_has_invalidation() const {
137     return next_activate_has_invalidation_;
138   }
139
140  private:
141   void AdvanceReporterStage(PipelineStage start, PipelineStage target);
142   bool CanSubmitImplFrame(const viz::BeginFrameId& id) const;
143   bool CanSubmitMainFrame(const viz::BeginFrameId& id) const;
144   std::unique_ptr<CompositorFrameReporter> RestoreReporterAtBeginImpl(
145       const viz::BeginFrameId& id);
146   CompositorFrameReporter::SmoothThread GetSmoothThread() const;
147   CompositorFrameReporter::SmoothThread GetSmoothThreadAtTime(
148       base::TimeTicks timestamp) const;
149
150   // Checks whether there are reporters containing updates from the main
151   // thread, and returns a pointer to that reporter (if any). Otherwise
152   // returns nullptr.
153   CompositorFrameReporter* GetOutstandingUpdatesFromMain(
154       const viz::BeginFrameId& id) const;
155
156   // If the display-compositor skips over some frames (e.g. when the gpu is
157   // busy, or the client is non-responsive), then it will not issue any
158   // |BeginFrameArgs| for those frames. However, |CompositorFrameReporter|
159   // instances should still be created for these frames. The following
160   // functions accomplish this.
161   void ProcessSkippedFramesIfNecessary(const viz::BeginFrameArgs& args);
162   void CreateReportersForDroppedFrames(
163       const viz::BeginFrameArgs& old_args,
164       const viz::BeginFrameArgs& new_args) const;
165
166   // The arg is a reference to the unique_ptr, because depending on the state
167   // that reporter is in, its ownership might be pass or not.
168   void SetPartialUpdateDeciderWhenWaitingOnMain(
169       std::unique_ptr<CompositorFrameReporter>& reporter);
170   void TrackSwapTiming(const viz::FrameTimingDetails& details);
171   void ReportMultipleSwaps(base::TimeTicks begin_frame_time,
172                            base::TimeDelta interval);
173
174   void AddSortedFrame(const viz::BeginFrameArgs& args,
175                       const FrameInfo& frame_info);
176
177   const bool should_report_histograms_;
178   const int layer_tree_host_id_;
179
180   viz::BeginFrameId last_submitted_frame_id_;
181
182   bool next_activate_has_invalidation_ = false;
183   ActiveTrackers active_trackers_;
184   FrameInfo::SmoothEffectDrivingThread scrolling_thread_ =
185       FrameInfo::SmoothEffectDrivingThread::kUnknown;
186
187   bool is_compositor_thread_driving_smoothness_ = false;
188   bool is_main_thread_driving_smoothness_ = false;
189   // Sorted history of smooththread. Element i indicating the smooththread
190   // from timestamp of element i-1 until timestamp of element i.
191   std::map<base::TimeTicks, CompositorFrameReporter::SmoothThread>
192       smooth_thread_history_;
193
194   // The latency reporter passed to each CompositorFrameReporter. Owned here
195   // because it must be common among all reporters.
196   // DO NOT reorder this line and the ones below. The latency_ukm_reporter_
197   // must outlive the objects in |submitted_compositor_frames_|.
198   std::unique_ptr<LatencyUkmReporter> latency_ukm_reporter_;
199
200   std::unique_ptr<CompositorFrameReporter>
201       reporters_[PipelineStage::kNumPipelineStages];
202
203   // Mapping of frame token to pipeline reporter for submitted compositor
204   // frames.
205   // DO NOT reorder this line and the one above. The latency_ukm_reporter_
206   // must outlive the objects in |submitted_compositor_frames_|.
207   base::circular_deque<SubmittedCompositorFrame> submitted_compositor_frames_;
208
209   // Contains information about the latest frame that was started, and the state
210   // during that frame. This is used to process skipped frames, as well as
211   // making sure a CompositorFrameReporter object for a delayed main-frame is
212   // created with the correct state.
213   struct {
214     viz::BeginFrameArgs args;
215     FrameInfo::SmoothEffectDrivingThread scrolling_thread =
216         FrameInfo::SmoothEffectDrivingThread::kUnknown;
217     ActiveTrackers active_trackers;
218     CompositorFrameReporter::SmoothThread smooth_thread =
219         CompositorFrameReporter::SmoothThread::kSmoothNone;
220   } last_started_compositor_frame_;
221
222   base::TimeTicks begin_main_frame_start_time_;
223
224   raw_ptr<const base::TickClock> tick_clock_ =
225       base::DefaultTickClock::GetInstance();
226
227   GlobalMetricsTrackers global_trackers_;
228
229   // When a frame with events metrics fails to be presented, its events metrics
230   // will be added to this map. The first following presented frame will get
231   // these metrics and report them.
232   std::map<viz::BeginFrameId, EventMetrics::List>
233       events_metrics_from_dropped_frames_;
234
235   // Tracking the swap times in a queue to measure delta of multiple swaps in
236   // each vsync.
237   std::queue<base::TimeTicks> latest_swap_times_;
238
239   // interval of last begin frame args.
240   base::TimeDelta last_interval_;
241
242   CompositorFrameReporter::CompositorLatencyInfo
243       previous_latency_predictions_main_;
244   CompositorFrameReporter::CompositorLatencyInfo
245       previous_latency_predictions_impl_;
246
247   // Container that stores the EventLatency stage latency predictions based on
248   // previous event traces.
249   CompositorFrameReporter::EventLatencyInfo event_latency_predictions_;
250 };
251
252 }  // namespace cc
253
254 #endif  // CC_METRICS_COMPOSITOR_FRAME_REPORTING_CONTROLLER_H_