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.
5 #ifndef CC_METRICS_COMPOSITOR_FRAME_REPORTING_CONTROLLER_H_
6 #define CC_METRICS_COMPOSITOR_FRAME_REPORTING_CONTROLLER_H_
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"
22 struct FrameTimingDetails;
26 class DroppedFrameCounter;
27 class EventLatencyTracker;
29 struct BeginMainFrameMetrics;
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 {
40 // Used as indices for accessing CompositorFrameReporters.
50 CompositorFrameReportingController(bool should_report_histograms,
51 bool should_report_ukm,
52 int layer_tree_host_id);
53 virtual ~CompositorFrameReportingController();
55 CompositorFrameReportingController(
56 const CompositorFrameReportingController&) = delete;
57 CompositorFrameReportingController& operator=(
58 const CompositorFrameReportingController&) = delete;
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(
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(
82 const viz::FrameTimingDetails& details);
83 void OnStoppedRequestingBeginFrames();
85 void NotifyReadyToCommit(std::unique_ptr<BeginMainFrameMetrics> details);
87 void SetUkmManager(UkmManager* manager);
89 void AddActiveTracker(FrameSequenceTrackerType type);
90 void RemoveActiveTracker(FrameSequenceTrackerType type);
91 void SetScrollingThread(FrameInfo::SmoothEffectDrivingThread thread);
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_;
100 void set_tick_clock(const base::TickClock* tick_clock) {
102 tick_clock_ = tick_clock;
105 std::unique_ptr<CompositorFrameReporter>* reporters() { return reporters_; }
107 void SetDroppedFrameCounter(DroppedFrameCounter* counter);
109 void SetFrameSequenceTrackerCollection(
110 FrameSequenceTrackerCollection* frame_sequence_trackers) {
111 global_trackers_.frame_sequence_trackers = frame_sequence_trackers;
114 void set_event_latency_tracker(EventLatencyTracker* event_latency_tracker) {
115 global_trackers_.event_latency_tracker = event_latency_tracker;
118 void BeginMainFrameStarted(base::TimeTicks begin_main_frame_start_time) {
119 begin_main_frame_start_time_ = begin_main_frame_start_time;
122 bool HasReporterAt(PipelineStage stage) const;
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();
134 base::TimeTicks Now() const;
136 bool next_activate_has_invalidation() const {
137 return next_activate_has_invalidation_;
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;
150 // Checks whether there are reporters containing updates from the main
151 // thread, and returns a pointer to that reporter (if any). Otherwise
153 CompositorFrameReporter* GetOutstandingUpdatesFromMain(
154 const viz::BeginFrameId& id) const;
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;
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);
174 void AddSortedFrame(const viz::BeginFrameArgs& args,
175 const FrameInfo& frame_info);
177 const bool should_report_histograms_;
178 const int layer_tree_host_id_;
180 viz::BeginFrameId last_submitted_frame_id_;
182 bool next_activate_has_invalidation_ = false;
183 ActiveTrackers active_trackers_;
184 FrameInfo::SmoothEffectDrivingThread scrolling_thread_ =
185 FrameInfo::SmoothEffectDrivingThread::kUnknown;
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_;
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_;
200 std::unique_ptr<CompositorFrameReporter>
201 reporters_[PipelineStage::kNumPipelineStages];
203 // Mapping of frame token to pipeline reporter for submitted compositor
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_;
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.
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_;
222 base::TimeTicks begin_main_frame_start_time_;
224 raw_ptr<const base::TickClock> tick_clock_ =
225 base::DefaultTickClock::GetInstance();
227 GlobalMetricsTrackers global_trackers_;
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_;
235 // Tracking the swap times in a queue to measure delta of multiple swaps in
237 std::queue<base::TimeTicks> latest_swap_times_;
239 // interval of last begin frame args.
240 base::TimeDelta last_interval_;
242 CompositorFrameReporter::CompositorLatencyInfo
243 previous_latency_predictions_main_;
244 CompositorFrameReporter::CompositorLatencyInfo
245 previous_latency_predictions_impl_;
247 // Container that stores the EventLatency stage latency predictions based on
248 // previous event traces.
249 CompositorFrameReporter::EventLatencyInfo event_latency_predictions_;
254 #endif // CC_METRICS_COMPOSITOR_FRAME_REPORTING_CONTROLLER_H_