1 // Copyright 2019 The Chromium Authors. All rights reserved. 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 <memory> 9 #include <vector> 10 11 #include "base/time/default_tick_clock.h" 12 #include "base/time/time.h" 13 #include "cc/cc_export.h" 14 #include "cc/metrics/compositor_frame_reporter.h" 15 #include "cc/metrics/event_metrics.h" 16 #include "cc/metrics/frame_sequence_metrics.h" 17 18 namespace viz { 19 struct FrameTimingDetails; 20 } 21 22 namespace cc { 23 class DroppedFrameCounter; 24 class UkmManager; 25 struct BeginMainFrameMetrics; 26 27 // This is used for managing simultaneous CompositorFrameReporter instances 28 // in the case that the compositor has high latency. Calling one of the 29 // event functions will begin recording the time of the corresponding 30 // phase and trace it. If the frame is eventually submitted, then the 31 // recorded times of each phase will be reported in UMA. 32 // See CompositorFrameReporter. 33 class CC_EXPORT CompositorFrameReportingController { 34 public: 35 // Used as indices for accessing CompositorFrameReporters. 36 enum PipelineStage { 37 kBeginImplFrame = 0, 38 kBeginMainFrame, 39 kCommit, 40 kActivate, 41 kNumPipelineStages 42 }; 43 44 CompositorFrameReportingController(bool should_report_metrics, 45 int layer_tree_host_id); 46 virtual ~CompositorFrameReportingController(); 47 48 CompositorFrameReportingController( 49 const CompositorFrameReportingController&) = delete; 50 CompositorFrameReportingController& operator=( 51 const CompositorFrameReportingController&) = delete; 52 53 // Events to signal Beginning/Ending of phases. 54 virtual void WillBeginImplFrame(const viz::BeginFrameArgs& args); 55 virtual void WillBeginMainFrame(const viz::BeginFrameArgs& args); 56 virtual void BeginMainFrameAborted(const viz::BeginFrameId& id); 57 virtual void WillInvalidateOnImplSide(); 58 virtual void WillCommit(); 59 virtual void DidCommit(); 60 virtual void WillActivate(); 61 virtual void DidActivate(); 62 virtual void DidSubmitCompositorFrame( 63 uint32_t frame_token, 64 const viz::BeginFrameId& current_frame_id, 65 const viz::BeginFrameId& last_activated_frame_id, 66 EventMetricsSet events_metrics); 67 virtual void DidNotProduceFrame(const viz::BeginFrameId& id, 68 FrameSkippedReason skip_reason); 69 virtual void OnFinishImplFrame(const viz::BeginFrameId& id); 70 virtual void DidPresentCompositorFrame( 71 uint32_t frame_token, 72 const viz::FrameTimingDetails& details); 73 void OnStoppedRequestingBeginFrames(); 74 75 void SetBlinkBreakdown(std::unique_ptr<BeginMainFrameMetrics> details, 76 base::TimeTicks main_thread_start_time); 77 78 void SetUkmManager(UkmManager* manager); 79 80 void AddActiveTracker(FrameSequenceTrackerType type); 81 void RemoveActiveTracker(FrameSequenceTrackerType type); 82 83 void SetThreadAffectsSmoothness(FrameSequenceMetrics::ThreadType thread_type, 84 bool affects_smoothness); 85 set_tick_clock(const base::TickClock * tick_clock)86 void set_tick_clock(const base::TickClock* tick_clock) { 87 DCHECK(tick_clock); 88 tick_clock_ = tick_clock; 89 } 90 reporters()91 std::unique_ptr<CompositorFrameReporter>* reporters() { return reporters_; } 92 SetDroppedFrameCounter(DroppedFrameCounter * counter)93 void SetDroppedFrameCounter(DroppedFrameCounter* counter) { 94 dropped_frame_counter_ = counter; 95 } 96 97 protected: 98 struct SubmittedCompositorFrame { 99 uint32_t frame_token; 100 std::unique_ptr<CompositorFrameReporter> reporter; 101 SubmittedCompositorFrame(); 102 SubmittedCompositorFrame(uint32_t frame_token, 103 std::unique_ptr<CompositorFrameReporter> reporter); 104 SubmittedCompositorFrame(SubmittedCompositorFrame&& other); 105 ~SubmittedCompositorFrame(); 106 }; 107 base::TimeTicks Now() const; 108 109 bool HasReporterAt(PipelineStage stage) const; next_activate_has_invalidation()110 bool next_activate_has_invalidation() const { 111 return next_activate_has_invalidation_; 112 } 113 114 private: 115 void AdvanceReporterStage(PipelineStage start, PipelineStage target); 116 bool CanSubmitImplFrame(const viz::BeginFrameId& id) const; 117 bool CanSubmitMainFrame(const viz::BeginFrameId& id) const; 118 std::unique_ptr<CompositorFrameReporter> RestoreReporterAtBeginImpl( 119 const viz::BeginFrameId& id); 120 CompositorFrameReporter::SmoothThread GetSmoothThread() const; 121 122 // If the display-compositor skips over some frames (e.g. when the gpu is 123 // busy, or the client is non-responsive), then it will not issue any 124 // |BeginFrameArgs| for those frames. However, |CompositorFrameReporter| 125 // instances should still be created for these frames. The following 126 // functions accomplish this. 127 void ProcessSkippedFramesIfNecessary(const viz::BeginFrameArgs& args); 128 void CreateReportersForDroppedFrames( 129 const viz::BeginFrameArgs& old_args, 130 const viz::BeginFrameArgs& new_args) const; 131 132 const bool should_report_metrics_; 133 const int layer_tree_host_id_; 134 135 viz::BeginFrameId last_submitted_frame_id_; 136 137 bool next_activate_has_invalidation_ = false; 138 CompositorFrameReporter::ActiveTrackers active_trackers_; 139 140 bool is_compositor_thread_driving_smoothness_ = false; 141 bool is_main_thread_driving_smoothness_ = false; 142 143 // The latency reporter passed to each CompositorFrameReporter. Owned here 144 // because it must be common among all reporters. 145 // DO NOT reorder this line and the ones below. The latency_ukm_reporter_ must 146 // outlive the objects in |submitted_compositor_frames_|. 147 std::unique_ptr<LatencyUkmReporter> latency_ukm_reporter_; 148 149 std::unique_ptr<CompositorFrameReporter> 150 reporters_[PipelineStage::kNumPipelineStages]; 151 152 // Mapping of frame token to pipeline reporter for submitted compositor 153 // frames. 154 // DO NOT reorder this line and the one above. The latency_ukm_reporter_ must 155 // outlive the objects in |submitted_compositor_frames_|. 156 base::circular_deque<SubmittedCompositorFrame> submitted_compositor_frames_; 157 158 // The latest frame that was started. 159 viz::BeginFrameArgs previous_frame_; 160 161 const base::TickClock* tick_clock_ = base::DefaultTickClock::GetInstance(); 162 163 DroppedFrameCounter* dropped_frame_counter_ = nullptr; 164 }; 165 } // namespace cc 166 167 #endif // CC_METRICS_COMPOSITOR_FRAME_REPORTING_CONTROLLER_H_ 168