1 // Copyright 2013 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_BASE_DEVTOOLS_INSTRUMENTATION_H_
6 #define CC_BASE_DEVTOOLS_INSTRUMENTATION_H_
7 
8 #include <stdint.h>
9 
10 #include <memory>
11 
12 #include "base/metrics/histogram_functions.h"
13 #include "base/metrics/histogram_macros.h"
14 #include "base/trace_event/trace_event.h"
15 #include "base/trace_event/traced_value.h"
16 #include "cc/base/base_export.h"
17 
18 namespace cc {
19 namespace devtools_instrumentation {
20 
21 namespace internal {
22 struct CC_BASE_EXPORT CategoryName {
23   // Put these strings into a struct to allow external linkage.
24   static constexpr const char kTimeline[] =
25       TRACE_DISABLED_BY_DEFAULT("devtools.timeline");
26   static constexpr const char kTimelineFrame[] =
27       TRACE_DISABLED_BY_DEFAULT("devtools.timeline.frame");
28 };
29 
30 CC_BASE_EXPORT extern const char kData[];
31 CC_BASE_EXPORT extern const char kFrameId[];
32 CC_BASE_EXPORT extern const char kLayerId[];
33 CC_BASE_EXPORT extern const char kLayerTreeId[];
34 CC_BASE_EXPORT extern const char kPixelRefId[];
35 
36 CC_BASE_EXPORT extern const char kImageDecodeTask[];
37 CC_BASE_EXPORT extern const char kBeginFrame[];
38 CC_BASE_EXPORT extern const char kNeedsBeginFrameChanged[];
39 CC_BASE_EXPORT extern const char kActivateLayerTree[];
40 CC_BASE_EXPORT extern const char kRequestMainThreadFrame[];
41 CC_BASE_EXPORT extern const char kDroppedFrame[];
42 CC_BASE_EXPORT extern const char kBeginMainThreadFrame[];
43 CC_BASE_EXPORT extern const char kDrawFrame[];
44 CC_BASE_EXPORT extern const char kCompositeLayers[];
45 }  // namespace internal
46 
47 extern const char kPaintSetup[];
48 CC_BASE_EXPORT extern const char kUpdateLayer[];
49 
50 class CC_BASE_EXPORT ScopedLayerTask {
51  public:
ScopedLayerTask(const char * event_name,int layer_id)52   ScopedLayerTask(const char* event_name, int layer_id)
53       : event_name_(event_name) {
54     TRACE_EVENT_BEGIN1(internal::CategoryName::kTimeline, event_name_,
55                        internal::kLayerId, layer_id);
56   }
57   ScopedLayerTask(const ScopedLayerTask&) = delete;
~ScopedLayerTask()58   ~ScopedLayerTask() {
59     TRACE_EVENT_END0(internal::CategoryName::kTimeline, event_name_);
60   }
61 
62   ScopedLayerTask& operator=(const ScopedLayerTask&) = delete;
63 
64  private:
65   const char* event_name_;
66 };
67 
68 class CC_BASE_EXPORT ScopedImageTask {
69  public:
70   enum ImageType { kAvif, kBmp, kGif, kIco, kJpeg, kPng, kWebP, kOther };
71 
ScopedImageTask(ImageType image_type)72   explicit ScopedImageTask(ImageType image_type)
73       : image_type_(image_type), start_time_(base::TimeTicks::Now()) {}
74   ScopedImageTask(const ScopedImageTask&) = delete;
75   ~ScopedImageTask() = default;
76   ScopedImageTask& operator=(const ScopedImageTask&) = delete;
77 
78   // Prevents logging duration metrics. Used in cases where a task performed
79   // uninteresting work or was terminated early.
SuppressMetrics()80   void SuppressMetrics() { suppress_metrics_ = true; }
81 
82  protected:
83   bool suppress_metrics_ = false;
84   const ImageType image_type_;
85   const base::TimeTicks start_time_;
86 
87   // UMA histogram parameters
88   const uint32_t bucket_count_ = 50;
89   base::TimeDelta hist_min_ = base::TimeDelta::FromMicroseconds(1);
90   base::TimeDelta hist_max_ = base::TimeDelta::FromMilliseconds(1000);
91 };
92 
93 class CC_BASE_EXPORT ScopedImageUploadTask : public ScopedImageTask {
94  public:
95   ScopedImageUploadTask(const void* image_ptr, ImageType image_type);
96   ScopedImageUploadTask(const ScopedImageUploadTask&) = delete;
97   ~ScopedImageUploadTask();
98 
99   ScopedImageUploadTask& operator=(const ScopedImageUploadTask&) = delete;
100 };
101 
102 class CC_BASE_EXPORT ScopedImageDecodeTask : public ScopedImageTask {
103  public:
104   enum TaskType { kInRaster, kOutOfRaster };
105   enum DecodeType { kSoftware, kGpu };
106 
107   ScopedImageDecodeTask(const void* image_ptr,
108                         DecodeType decode_type,
109                         TaskType task_type,
110                         ImageType image_type);
111   ScopedImageDecodeTask(const ScopedImageDecodeTask&) = delete;
112   ~ScopedImageDecodeTask();
113 
114   ScopedImageDecodeTask& operator=(const ScopedImageDecodeTask&) = delete;
115 
116  private:
117   const DecodeType decode_type_;
118   const TaskType task_type_;
119 };
120 
121 class CC_BASE_EXPORT ScopedLayerTreeTask {
122  public:
ScopedLayerTreeTask(const char * event_name,int layer_id,int layer_tree_host_id)123   ScopedLayerTreeTask(const char* event_name,
124                       int layer_id,
125                       int layer_tree_host_id)
126       : event_name_(event_name) {
127     TRACE_EVENT_BEGIN2(internal::CategoryName::kTimeline, event_name_,
128                        internal::kLayerId, layer_id, internal::kLayerTreeId,
129                        layer_tree_host_id);
130   }
131   ScopedLayerTreeTask(const ScopedLayerTreeTask&) = delete;
~ScopedLayerTreeTask()132   ~ScopedLayerTreeTask() {
133     TRACE_EVENT_END0(internal::CategoryName::kTimeline, event_name_);
134   }
135 
136   ScopedLayerTreeTask& operator=(const ScopedLayerTreeTask&) = delete;
137 
138  private:
139   const char* event_name_;
140 };
141 
142 struct CC_BASE_EXPORT ScopedCommitTrace {
143  public:
ScopedCommitTraceScopedCommitTrace144   explicit ScopedCommitTrace(int layer_tree_host_id) {
145     TRACE_EVENT_BEGIN1(internal::CategoryName::kTimeline,
146                        internal::kCompositeLayers, internal::kLayerTreeId,
147                        layer_tree_host_id);
148   }
149   ScopedCommitTrace(const ScopedCommitTrace&) = delete;
~ScopedCommitTraceScopedCommitTrace150   ~ScopedCommitTrace() {
151     TRACE_EVENT_END0(internal::CategoryName::kTimeline,
152                      internal::kCompositeLayers);
153   }
154 
155   ScopedCommitTrace& operator=(const ScopedCommitTrace&) = delete;
156 };
157 
158 struct CC_BASE_EXPORT ScopedLayerObjectTracker
159     : public base::trace_event::
160           TraceScopedTrackableObject<int, internal::CategoryName::kTimeline> {
ScopedLayerObjectTrackerScopedLayerObjectTracker161   explicit ScopedLayerObjectTracker(int layer_id)
162       : base::trace_event::
163             TraceScopedTrackableObject<int, internal::CategoryName::kTimeline>(
164                 internal::kLayerId,
165                 layer_id) {}
166   ScopedLayerObjectTracker(const ScopedLayerObjectTracker&) = delete;
167   ScopedLayerObjectTracker& operator=(const ScopedLayerObjectTracker&) = delete;
168 };
169 
DidActivateLayerTree(int layer_tree_host_id,int frame_id)170 inline void CC_BASE_EXPORT DidActivateLayerTree(int layer_tree_host_id,
171                                                 int frame_id) {
172   TRACE_EVENT_INSTANT2(internal::CategoryName::kTimelineFrame,
173                        internal::kActivateLayerTree, TRACE_EVENT_SCOPE_THREAD,
174                        internal::kLayerTreeId, layer_tree_host_id,
175                        internal::kFrameId, frame_id);
176 }
177 
DidBeginFrame(int layer_tree_host_id)178 inline void CC_BASE_EXPORT DidBeginFrame(int layer_tree_host_id) {
179   TRACE_EVENT_INSTANT1(internal::CategoryName::kTimelineFrame,
180                        internal::kBeginFrame, TRACE_EVENT_SCOPE_THREAD,
181                        internal::kLayerTreeId, layer_tree_host_id);
182 }
183 
DidDrawFrame(int layer_tree_host_id)184 inline void CC_BASE_EXPORT DidDrawFrame(int layer_tree_host_id) {
185   TRACE_EVENT_INSTANT1(internal::CategoryName::kTimelineFrame,
186                        internal::kDrawFrame, TRACE_EVENT_SCOPE_THREAD,
187                        internal::kLayerTreeId, layer_tree_host_id);
188 }
189 
DidRequestMainThreadFrame(int layer_tree_host_id)190 inline void CC_BASE_EXPORT DidRequestMainThreadFrame(int layer_tree_host_id) {
191   TRACE_EVENT_INSTANT1(
192       internal::CategoryName::kTimelineFrame, internal::kRequestMainThreadFrame,
193       TRACE_EVENT_SCOPE_THREAD, internal::kLayerTreeId, layer_tree_host_id);
194 }
195 
196 inline void CC_BASE_EXPORT
DidDropSmoothnessFrame(int layer_tree_host_id,base::TimeTicks dropped_frame_timestamp)197 DidDropSmoothnessFrame(int layer_tree_host_id,
198                        base::TimeTicks dropped_frame_timestamp) {
199   TRACE_EVENT_INSTANT_WITH_TIMESTAMP1(
200       internal::CategoryName::kTimelineFrame, internal::kDroppedFrame,
201       TRACE_EVENT_SCOPE_THREAD, dropped_frame_timestamp, internal::kLayerTreeId,
202       layer_tree_host_id);
203 }
204 
205 inline std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
BeginMainThreadFrameData(int frame_id)206 BeginMainThreadFrameData(int frame_id) {
207   std::unique_ptr<base::trace_event::TracedValue> value(
208       new base::trace_event::TracedValue());
209   value->SetInteger("frameId", frame_id);
210   return std::move(value);
211 }
212 
WillBeginMainThreadFrame(int layer_tree_host_id,int frame_id)213 inline void CC_BASE_EXPORT WillBeginMainThreadFrame(int layer_tree_host_id,
214                                                     int frame_id) {
215   TRACE_EVENT_INSTANT2(
216       internal::CategoryName::kTimelineFrame, internal::kBeginMainThreadFrame,
217       TRACE_EVENT_SCOPE_THREAD, internal::kLayerTreeId, layer_tree_host_id,
218       internal::kData, BeginMainThreadFrameData(frame_id));
219 }
220 
221 inline std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
NeedsBeginFrameData(bool needs_begin_frame)222 NeedsBeginFrameData(bool needs_begin_frame) {
223   std::unique_ptr<base::trace_event::TracedValue> value(
224       new base::trace_event::TracedValue());
225   value->SetInteger("needsBeginFrame", needs_begin_frame);
226   return std::move(value);
227 }
228 
NeedsBeginFrameChanged(int layer_tree_host_id,bool new_value)229 inline void CC_BASE_EXPORT NeedsBeginFrameChanged(int layer_tree_host_id,
230                                                   bool new_value) {
231   TRACE_EVENT_INSTANT2(
232       internal::CategoryName::kTimelineFrame, internal::kNeedsBeginFrameChanged,
233       TRACE_EVENT_SCOPE_THREAD, internal::kLayerTreeId, layer_tree_host_id,
234       internal::kData, NeedsBeginFrameData(new_value));
235 }
236 
237 }  // namespace devtools_instrumentation
238 }  // namespace cc
239 
240 #endif  // CC_BASE_DEVTOOLS_INSTRUMENTATION_H_
241