• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015 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 #ifndef SkTraceEventCommon_DEFINED
5 #define SkTraceEventCommon_DEFINED
6 
7 #include "include/core/SkTypes.h"
8 #include "include/utils/SkTraceEventPhase.h"
9 
10 // Trace events are for tracking application performance and resource usage.
11 // Macros are provided to track:
12 //    Duration of scoped regions
13 //    Instantaneous events
14 //    Counters
15 //
16 // The first two arguments to all TRACE macros are the category and name. Both are strings, and
17 // must have application lifetime (statics or literals). The same applies to arg_names, and string
18 // argument values. However, you can force a copy of a string argument value with TRACE_STR_COPY:
19 //     TRACE_EVENT1("category", "name", "arg1", "literal string is only referenced");
20 //     TRACE_EVENT1("category", "name", "arg1", TRACE_STR_COPY("string will be copied"));
21 //
22 //
23 // Categories are used to group events, and
24 // can be enabled or disabled by the tracing framework. The trace system will automatically add the
25 // process id, thread id, and microsecond timestamp to all events.
26 //
27 //
28 // The TRACE_EVENT[0-2] macros trace the duration of entire scopes:
29 //   void doSomethingCostly() {
30 //     TRACE_EVENT0("MY_SUBSYSTEM", "doSomethingCostly");
31 //     ...
32 //   }
33 //
34 // Additional parameters can be associated with an event:
35 //   void doSomethingCostly2(int howMuch) {
36 //     TRACE_EVENT1("MY_SUBSYSTEM", "doSomethingCostly", "howMuch", howMuch);
37 //     ...
38 //   }
39 //
40 //
41 // Trace event also supports counters, which is a way to track a quantity as it varies over time.
42 // Counters are created with the following macro:
43 //   TRACE_COUNTER1("MY_SUBSYSTEM", "myCounter", g_myCounterValue);
44 //
45 // Counters are process-specific. The macro itself can be issued from any thread, however.
46 //
47 // Sometimes, you want to track two counters at once. You can do this with two counter macros:
48 //   TRACE_COUNTER1("MY_SUBSYSTEM", "myCounter0", g_myCounterValue[0]);
49 //   TRACE_COUNTER1("MY_SUBSYSTEM", "myCounter1", g_myCounterValue[1]);
50 // Or you can do it with a combined macro:
51 //   TRACE_COUNTER2("MY_SUBSYSTEM", "myCounter",
52 //                  "bytesPinned", g_myCounterValue[0],
53 //                  "bytesAllocated", g_myCounterValue[1]);
54 // The tracing UI will show these counters in a single graph, as a summed area chart.
55 
56 #if defined(TRACE_EVENT0)
57 #error "Another copy of this file has already been included."
58 #endif
59 
60 #define TRACE_EMPTY do {} while (0)
61 
62 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
63 
64 #include <cutils/trace.h>
65 #include <stdarg.h>
66 
67 class SkAndroidFrameworkTraceUtil {
68 public:
SkAndroidFrameworkTraceUtil(const char * name)69     SkAndroidFrameworkTraceUtil(const char* name) {
70         if (CC_UNLIKELY(gEnableAndroidTracing)) {
71             ATRACE_BEGIN(name);
72         }
73     }
SkAndroidFrameworkTraceUtil(bool,const char * fmt,...)74     SkAndroidFrameworkTraceUtil(bool, const char* fmt, ...) {
75         if (CC_LIKELY((!gEnableAndroidTracing) || (!ATRACE_ENABLED()))) return;
76 
77         const int BUFFER_SIZE = 256;
78         va_list ap;
79         char buf[BUFFER_SIZE];
80 
81         va_start(ap, fmt);
82         vsnprintf(buf, BUFFER_SIZE, fmt, ap);
83         va_end(ap);
84 
85         ATRACE_BEGIN(buf);
86     }
~SkAndroidFrameworkTraceUtil()87     ~SkAndroidFrameworkTraceUtil() {
88         if (CC_UNLIKELY(gEnableAndroidTracing)) {
89             ATRACE_END();
90         }
91     }
92 
setEnableTracing(bool enableAndroidTracing)93     static void setEnableTracing(bool enableAndroidTracing) {
94         gEnableAndroidTracing = enableAndroidTracing;
95     }
96 
getEnableTracing()97     static bool getEnableTracing() {
98         return gEnableAndroidTracing;
99     }
100 
101 private:
102     static bool gEnableAndroidTracing;
103 };
104 
105 #define ATRACE_ANDROID_FRAMEWORK(fmt, ...) SkAndroidFrameworkTraceUtil __trace(true, fmt, ##__VA_ARGS__)
106 
107 // Records a pair of begin and end events called "name" for the current scope, with 0, 1 or 2
108 // associated arguments. In the framework, the arguments are ignored.
109 #define TRACE_EVENT0(category_group, name) \
110     SkAndroidFrameworkTraceUtil __trace(name)
111 #define TRACE_EVENT1(category_group, name, arg1_name, arg1_val) \
112     SkAndroidFrameworkTraceUtil __trace(name)
113 #define TRACE_EVENT2(category_group, name, arg1_name, arg1_val, arg2_name, arg2_val) \
114     SkAndroidFrameworkTraceUtil __trace(name)
115 
116 // Records a single event called "name" immediately, with 0, 1 or 2 associated arguments. If the
117 // category is not enabled, then this does nothing.
118 #define TRACE_EVENT_INSTANT0(category_group, name, scope) \
119     do { SkAndroidFrameworkTraceUtil __trace(name); } while(0)
120 
121 #define TRACE_EVENT_INSTANT1(category_group, name, scope, arg1_name, arg1_val) \
122     do { SkAndroidFrameworkTraceUtil __trace(name); } while(0)
123 
124 #define TRACE_EVENT_INSTANT2(category_group, name, scope, arg1_name, arg1_val, \
125                              arg2_name, arg2_val)                              \
126     do { SkAndroidFrameworkTraceUtil __trace(name); } while(0)
127 
128 // Records the value of a counter called "name" immediately. Value
129 // must be representable as a 32 bit integer.
130 #define TRACE_COUNTER1(category_group, name, value) \
131     if (CC_UNLIKELY(SkAndroidFrameworkTraceUtil::getEnableTracing())) { \
132         ATRACE_INT(name, value); \
133     }
134 
135 // Records the values of a multi-parted counter called "name" immediately.
136 // In Chrome, this macro produces a stacked bar chart. ATrace doesn't support
137 // that, so this just produces two separate counters.
138 #define TRACE_COUNTER2(category_group, name, value1_name, value1_val, value2_name, value2_val) \
139     do { \
140         if (CC_UNLIKELY(SkAndroidFrameworkTraceUtil::getEnableTracing())) { \
141             ATRACE_INT(name "-" value1_name, value1_val); \
142             ATRACE_INT(name "-" value2_name, value2_val); \
143         } \
144     } while (0)
145 
146 // ATrace has no object tracking
147 #define TRACE_EVENT_OBJECT_CREATED_WITH_ID(category_group, name, id) TRACE_EMPTY
148 #define TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(category_group, name, id, snapshot) TRACE_EMPTY
149 #define TRACE_EVENT_OBJECT_DELETED_WITH_ID(category_group, name, id) TRACE_EMPTY
150 
151 // Macro to efficiently determine if a given category group is enabled.
152 // This is only used for some shader text logging that isn't supported in ATrace anyway.
153 #define TRACE_EVENT_CATEGORY_GROUP_ENABLED(category_group, ret)             \
154   do { *ret = false; } while (0)
155 
156 #else // !SK_BUILD_FOR_ANDROID_FRAMEWORK
157 
158 #define ATRACE_ANDROID_FRAMEWORK(fmt, ...) TRACE_EMPTY
159 
160 #ifdef SK_BUILD_FOR_OHOS
161 
162 #include "hitrace_meter.h"
163 
164 class SkOHOSTraceUtil {
165 public:
SkOHOSTraceUtil(const char * name)166     SkOHOSTraceUtil(const char* name) {
167         StartTraceDebug(gEnableTracing, HITRACE_TAG_GRAPHIC_AGP, name, 0);
168     }
169 
~SkOHOSTraceUtil()170     ~SkOHOSTraceUtil() {
171         FinishTraceDebug(gEnableTracing, HITRACE_TAG_GRAPHIC_AGP);
172     }
173 
setEnableTracing(bool enableTracing)174     static void setEnableTracing(bool enableTracing) {
175         gEnableTracing = enableTracing;
176     }
177 
getEnableTracing()178     static bool getEnableTracing() {
179         return gEnableTracing;
180     }
181 
182 private:
183     static bool gEnableTracing;
184 };
185 
186 // Records a pair of begin and end events called "name" for the current scope, with 0, 1 or 2
187 // associated arguments. If the category is not enabled, then this does nothing.
188 #define TRACE_EVENT0(category_group, name) \
189     SkOHOSTraceUtil _trace(name); \
190     INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name)
191 
192 #define TRACE_EVENT1(category_group, name, arg1_name, arg1_val) \
193     SkOHOSTraceUtil _trace(name); \
194     INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name, arg1_name, arg1_val)
195 
196 #define TRACE_EVENT2(category_group, name, arg1_name, arg1_val, arg2_name, arg2_val) \
197     SkOHOSTraceUtil _trace(name); \
198     INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name, arg1_name, arg1_val, arg2_name, arg2_val)
199 
200 #define RS_SK_TRACE_NAME(name) SkOHOSTraceUtil __trace(name)
201 
202 #else  // !SK_BUILD_FOR_OHOS
203 
204 // Records a pair of begin and end events called "name" for the current scope, with 0, 1 or 2
205 // associated arguments. If the category is not enabled, then this does nothing.
206 #define TRACE_EVENT0(category_group, name) \
207     INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name)
208 
209 #define TRACE_EVENT1(category_group, name, arg1_name, arg1_val) \
210     INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name, arg1_name, arg1_val)
211 
212 #define TRACE_EVENT2(category_group, name, arg1_name, arg1_val, arg2_name, arg2_val) \
213     INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name, arg1_name, arg1_val, arg2_name, arg2_val)
214 
215 #define RS_SK_TRACE_NAME(name) TRACE_EMPTY
216 
217 #endif // #ifdef SK_BUILD_FOR_OHOS
218 
219 // Records a single event called "name" immediately, with 0, 1 or 2 associated arguments. If the
220 // category is not enabled, then this does nothing.
221 #define TRACE_EVENT_INSTANT0(category_group, name, scope)                   \
222   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name, \
223                            TRACE_EVENT_FLAG_NONE | scope)
224 
225 #define TRACE_EVENT_INSTANT1(category_group, name, scope, arg1_name, arg1_val) \
226   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name,    \
227                            TRACE_EVENT_FLAG_NONE | scope, arg1_name, arg1_val)
228 
229 #define TRACE_EVENT_INSTANT2(category_group, name, scope, arg1_name, arg1_val, \
230                              arg2_name, arg2_val)                              \
231   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name,    \
232                            TRACE_EVENT_FLAG_NONE | scope, arg1_name, arg1_val, \
233                            arg2_name, arg2_val)
234 
235 // Records the value of a counter called "name" immediately. Value
236 // must be representable as a 32 bit integer.
237 #define TRACE_COUNTER1(category_group, name, value)                         \
238   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, category_group, name, \
239                            TRACE_EVENT_FLAG_NONE, "value",                  \
240                            static_cast<int>(value))
241 
242 // Records the values of a multi-parted counter called "name" immediately.
243 // The UI will treat value1 and value2 as parts of a whole, displaying their
244 // values as a stacked-bar chart.
245 #define TRACE_COUNTER2(category_group, name, value1_name, value1_val,       \
246                        value2_name, value2_val)                             \
247   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, category_group, name, \
248                            TRACE_EVENT_FLAG_NONE, value1_name,              \
249                            static_cast<int>(value1_val), value2_name,       \
250                            static_cast<int>(value2_val))
251 
252 #define TRACE_EVENT_ASYNC_BEGIN0(category, name, id)                                           \
253     INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                                          \
254         TRACE_EVENT_PHASE_ASYNC_BEGIN, category, name, id, TRACE_EVENT_FLAG_NONE)
255 #define TRACE_EVENT_ASYNC_BEGIN1(category, name, id, arg1_name, arg1_val)                      \
256     INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN,                            \
257         category, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
258 #define TRACE_EVENT_ASYNC_BEGIN2(category, name, id, arg1_name, arg1_val, arg2_name, arg2_val) \
259     INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN,                            \
260         category, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, arg2_name, arg2_val)
261 
262 #define TRACE_EVENT_ASYNC_END0(category, name, id)                                           \
263     INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END,                            \
264         category, name, id, TRACE_EVENT_FLAG_NONE)
265 #define TRACE_EVENT_ASYNC_END1(category, name, id, arg1_name, arg1_val)                      \
266     INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END,                            \
267         category, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
268 #define TRACE_EVENT_ASYNC_END2(category, name, id, arg1_name, arg1_val, arg2_name, arg2_val) \
269     INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END,                            \
270         category, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, arg2_name, arg2_val)
271 
272 // Macros to track the life time and value of arbitrary client objects.
273 #define TRACE_EVENT_OBJECT_CREATED_WITH_ID(category_group, name, id) \
274   INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                  \
275       TRACE_EVENT_PHASE_CREATE_OBJECT, category_group, name, id,     \
276       TRACE_EVENT_FLAG_NONE)
277 
278 #define TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(category_group, name, id, \
279                                             snapshot)                 \
280   INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                   \
281       TRACE_EVENT_PHASE_SNAPSHOT_OBJECT, category_group, name,        \
282       id, TRACE_EVENT_FLAG_NONE, "snapshot", snapshot)
283 
284 #define TRACE_EVENT_OBJECT_DELETED_WITH_ID(category_group, name, id) \
285   INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                  \
286       TRACE_EVENT_PHASE_DELETE_OBJECT, category_group, name, id,     \
287       TRACE_EVENT_FLAG_NONE)
288 
289 // Macro to efficiently determine if a given category group is enabled.
290 #define TRACE_EVENT_CATEGORY_GROUP_ENABLED(category_group, ret)             \
291   do {                                                                      \
292     INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group);                 \
293     if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \
294       *ret = true;                                                          \
295     } else {                                                                \
296       *ret = false;                                                         \
297     }                                                                       \
298   } while (0)
299 
300 #endif
301 
302 // Flags for changing the behavior of TRACE_EVENT_API_ADD_TRACE_EVENT.
303 #define TRACE_EVENT_FLAG_NONE (static_cast<unsigned int>(0))
304 #define TRACE_EVENT_FLAG_COPY (static_cast<unsigned int>(1 << 0))
305 #define TRACE_EVENT_FLAG_HAS_ID (static_cast<unsigned int>(1 << 1))
306 #define TRACE_EVENT_FLAG_MANGLE_ID (static_cast<unsigned int>(1 << 2))
307 #define TRACE_EVENT_FLAG_SCOPE_OFFSET (static_cast<unsigned int>(1 << 3))
308 #define TRACE_EVENT_FLAG_SCOPE_EXTRA (static_cast<unsigned int>(1 << 4))
309 #define TRACE_EVENT_FLAG_EXPLICIT_TIMESTAMP (static_cast<unsigned int>(1 << 5))
310 #define TRACE_EVENT_FLAG_ASYNC_TTS (static_cast<unsigned int>(1 << 6))
311 #define TRACE_EVENT_FLAG_BIND_TO_ENCLOSING (static_cast<unsigned int>(1 << 7))
312 #define TRACE_EVENT_FLAG_FLOW_IN (static_cast<unsigned int>(1 << 8))
313 #define TRACE_EVENT_FLAG_FLOW_OUT (static_cast<unsigned int>(1 << 9))
314 #define TRACE_EVENT_FLAG_HAS_CONTEXT_ID (static_cast<unsigned int>(1 << 10))
315 
316 #define TRACE_EVENT_FLAG_SCOPE_MASK                          \
317   (static_cast<unsigned int>(TRACE_EVENT_FLAG_SCOPE_OFFSET | \
318                              TRACE_EVENT_FLAG_SCOPE_EXTRA))
319 
320 // Type values for identifying types in the TraceValue union.
321 #define TRACE_VALUE_TYPE_BOOL (static_cast<unsigned char>(1))
322 #define TRACE_VALUE_TYPE_UINT (static_cast<unsigned char>(2))
323 #define TRACE_VALUE_TYPE_INT (static_cast<unsigned char>(3))
324 #define TRACE_VALUE_TYPE_DOUBLE (static_cast<unsigned char>(4))
325 #define TRACE_VALUE_TYPE_POINTER (static_cast<unsigned char>(5))
326 #define TRACE_VALUE_TYPE_STRING (static_cast<unsigned char>(6))
327 #define TRACE_VALUE_TYPE_COPY_STRING (static_cast<unsigned char>(7))
328 #define TRACE_VALUE_TYPE_CONVERTABLE (static_cast<unsigned char>(8))
329 
330 // Enum reflecting the scope of an INSTANT event. Must fit within TRACE_EVENT_FLAG_SCOPE_MASK.
331 #define TRACE_EVENT_SCOPE_GLOBAL (static_cast<unsigned char>(0 << 3))
332 #define TRACE_EVENT_SCOPE_PROCESS (static_cast<unsigned char>(1 << 3))
333 #define TRACE_EVENT_SCOPE_THREAD (static_cast<unsigned char>(2 << 3))
334 
335 #define TRACE_EVENT_SCOPE_NAME_GLOBAL ('g')
336 #define TRACE_EVENT_SCOPE_NAME_PROCESS ('p')
337 #define TRACE_EVENT_SCOPE_NAME_THREAD ('t')
338 
339 #endif  // SkTraceEventCommon_DEFINED
340