blob: 199b487796588512e023007c7cc620b5bc3a3c00 [file] [log] [blame]
oysteinedfcba472015-08-05 12:54:40 -07001// 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.
Hal Canary03a7f5f2017-02-10 09:06:38 -05004#ifndef SkTraceEventCommon_DEFINED
5#define SkTraceEventCommon_DEFINED
oysteinedfcba472015-08-05 12:54:40 -07006
Cary Clarka6c75fd2018-06-19 16:00:31 -04007#include "SkTraceEventPhase.h"
Stan Ilievb7b9d022018-06-29 18:19:12 -04008#include "SkTypes.h"
Cary Clarka6c75fd2018-06-19 16:00:31 -04009
oysteinedfcba472015-08-05 12:54:40 -070010// Trace events are for tracking application performance and resource usage.
11// Macros are provided to track:
Brian Osman594838a2017-07-21 08:57:53 -040012// Duration of scoped regions
13// Instantaneous events
oysteinedfcba472015-08-05 12:54:40 -070014// Counters
15//
Brian Osman594838a2017-07-21 08:57:53 -040016// 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"));
oysteinedfcba472015-08-05 12:54:40 -070021//
oysteinedfcba472015-08-05 12:54:40 -070022//
Brian Osman594838a2017-07-21 08:57:53 -040023// 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.
oysteinedfcba472015-08-05 12:54:40 -070026//
oysteinedfcba472015-08-05 12:54:40 -070027//
Brian Osman594838a2017-07-21 08:57:53 -040028// The TRACE_EVENT[0-2] macros trace the duration of entire scopes:
oysteinedfcba472015-08-05 12:54:40 -070029// 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) {
Brian Osman594838a2017-07-21 08:57:53 -040036// TRACE_EVENT1("MY_SUBSYSTEM", "doSomethingCostly", "howMuch", howMuch);
oysteinedfcba472015-08-05 12:54:40 -070037// ...
38// }
39//
oysteinedfcba472015-08-05 12:54:40 -070040//
Brian Osman594838a2017-07-21 08:57:53 -040041// 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:
oysteinedfcba472015-08-05 12:54:40 -070043// TRACE_COUNTER1("MY_SUBSYSTEM", "myCounter", g_myCounterValue);
44//
Brian Osman594838a2017-07-21 08:57:53 -040045// Counters are process-specific. The macro itself can be issued from any thread, however.
oysteinedfcba472015-08-05 12:54:40 -070046//
Brian Osman594838a2017-07-21 08:57:53 -040047// Sometimes, you want to track two counters at once. You can do this with two counter macros:
oysteinedfcba472015-08-05 12:54:40 -070048// 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",
Brian Osman594838a2017-07-21 08:57:53 -040052// "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.
oysteinedfcba472015-08-05 12:54:40 -070055
56#if defined(TRACE_EVENT0)
57#error "Another copy of this file has already been included."
58#endif
59
Derek Sollenberger559f5342017-08-17 12:34:54 -040060#define TRACE_EMPTY do {} while (0)
61
Brian Osman26080be2017-08-11 09:53:35 -040062#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
63
Ben Wagnerc5828272018-03-13 12:11:06 -040064#include <cutils/trace.h>
Stan Ilievb7b9d022018-06-29 18:19:12 -040065class SkAndroidFrameworkTraceUtil {
66public:
Derek Sollenberger559f5342017-08-17 12:34:54 -040067 SkAndroidFrameworkTraceUtil(const char* name) {
Stan Ilievb7b9d022018-06-29 18:19:12 -040068 if (CC_UNLIKELY(gEnableAndroidTracing)) {
69 ATRACE_BEGIN(name);
70 }
Derek Sollenberger559f5342017-08-17 12:34:54 -040071 }
72 SkAndroidFrameworkTraceUtil(bool, const char* fmt, ...) {
Stan Ilievb7b9d022018-06-29 18:19:12 -040073 if (CC_LIKELY((!gEnableAndroidTracing) || (!ATRACE_ENABLED()))) return;
Derek Sollenberger559f5342017-08-17 12:34:54 -040074
75 const int BUFFER_SIZE = 256;
76 va_list ap;
77 char buf[BUFFER_SIZE];
78
79 va_start(ap, fmt);
80 vsnprintf(buf, BUFFER_SIZE, fmt, ap);
81 va_end(ap);
82
83 ATRACE_BEGIN(buf);
84 }
Stan Ilievb7b9d022018-06-29 18:19:12 -040085 ~SkAndroidFrameworkTraceUtil() {
86 if (CC_UNLIKELY(gEnableAndroidTracing)) {
87 ATRACE_END();
88 }
89 }
90
91 static void setEnableTracing(bool enableAndroidTracing) {
92 gEnableAndroidTracing = enableAndroidTracing;
93 }
94
95 static bool getEnableTracing() {
96 return gEnableAndroidTracing;
97 }
98
99private:
100 static bool gEnableAndroidTracing;
Derek Sollenberger559f5342017-08-17 12:34:54 -0400101};
102
103#define ATRACE_ANDROID_FRAMEWORK(fmt, ...) SkAndroidFrameworkTraceUtil __trace(true, fmt, ##__VA_ARGS__)
104
Brian Osman26080be2017-08-11 09:53:35 -0400105// Records a pair of begin and end events called "name" for the current scope, with 0, 1 or 2
106// associated arguments. In the framework, the arguments are ignored.
Brian Osman0db07792017-08-11 13:51:01 -0400107#define TRACE_EVENT0(category_group, name) \
108 SkAndroidFrameworkTraceUtil __trace(name)
109#define TRACE_EVENT1(category_group, name, arg1_name, arg1_val) \
110 SkAndroidFrameworkTraceUtil __trace(name)
111#define TRACE_EVENT2(category_group, name, arg1_name, arg1_val, arg2_name, arg2_val) \
112 SkAndroidFrameworkTraceUtil __trace(name)
Brian Osman26080be2017-08-11 09:53:35 -0400113
114// Records a single event called "name" immediately, with 0, 1 or 2 associated arguments. If the
115// category is not enabled, then this does nothing.
116#define TRACE_EVENT_INSTANT0(category_group, name, scope) \
117 do { SkAndroidFrameworkTraceUtil __trace(name); } while(0)
118
119#define TRACE_EVENT_INSTANT1(category_group, name, scope, arg1_name, arg1_val) \
120 do { SkAndroidFrameworkTraceUtil __trace(name); } while(0)
121
122#define TRACE_EVENT_INSTANT2(category_group, name, scope, arg1_name, arg1_val, \
123 arg2_name, arg2_val) \
124 do { SkAndroidFrameworkTraceUtil __trace(name); } while(0)
125
126// Records the value of a counter called "name" immediately. Value
127// must be representable as a 32 bit integer.
Stan Ilievb7b9d022018-06-29 18:19:12 -0400128#define TRACE_COUNTER1(category_group, name, value) \
129 if (CC_UNLIKELY(SkAndroidFrameworkTraceUtil::getEnableTracing())) { \
130 ATRACE_INT(name, value); \
131 }
Brian Osman26080be2017-08-11 09:53:35 -0400132
133// Records the values of a multi-parted counter called "name" immediately.
134// In Chrome, this macro produces a stacked bar chart. ATrace doesn't support
135// that, so this just produces two separate counters.
136#define TRACE_COUNTER2(category_group, name, value1_name, value1_val, value2_name, value2_val) \
137 do { \
Stan Ilievb7b9d022018-06-29 18:19:12 -0400138 if (CC_UNLIKELY(SkAndroidFrameworkTraceUtil::getEnableTracing())) { \
139 ATRACE_INT(name "-" value1_name, value1_val); \
140 ATRACE_INT(name "-" value2_name, value2_val); \
141 } \
Brian Osman26080be2017-08-11 09:53:35 -0400142 } while (0)
143
Brian Osman26080be2017-08-11 09:53:35 -0400144// ATrace has no object tracking
145#define TRACE_EVENT_OBJECT_CREATED_WITH_ID(category_group, name, id) TRACE_EMPTY
146#define TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(category_group, name, id, snapshot) TRACE_EMPTY
147#define TRACE_EVENT_OBJECT_DELETED_WITH_ID(category_group, name, id) TRACE_EMPTY
148
149// Macro to efficiently determine if a given category group is enabled.
150// This is only used for some shader text logging that isn't supported in ATrace anyway.
151#define TRACE_EVENT_CATEGORY_GROUP_ENABLED(category_group, ret) \
152 do { *ret = false; } while (0)
153
154#else // !SK_BUILD_FOR_ANDROID_FRAMEWORK
155
Derek Sollenberger559f5342017-08-17 12:34:54 -0400156#define ATRACE_ANDROID_FRAMEWORK(fmt, ...) TRACE_EMPTY
157
Brian Osman594838a2017-07-21 08:57:53 -0400158// Records a pair of begin and end events called "name" for the current scope, with 0, 1 or 2
159// associated arguments. If the category is not enabled, then this does nothing.
160#define TRACE_EVENT0(category_group, name) \
oysteinedfcba472015-08-05 12:54:40 -0700161 INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name)
Brian Osman3e583cb2017-07-19 14:39:47 -0400162
oysteinedfcba472015-08-05 12:54:40 -0700163#define TRACE_EVENT1(category_group, name, arg1_name, arg1_val) \
oysteinedfcba472015-08-05 12:54:40 -0700164 INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name, arg1_name, arg1_val)
Brian Osman3e583cb2017-07-19 14:39:47 -0400165
Brian Osman594838a2017-07-21 08:57:53 -0400166#define TRACE_EVENT2(category_group, name, arg1_name, arg1_val, arg2_name, arg2_val) \
167 INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name, arg1_name, arg1_val, arg2_name, arg2_val)
oysteinedfcba472015-08-05 12:54:40 -0700168
Brian Osman594838a2017-07-21 08:57:53 -0400169// Records a single event called "name" immediately, with 0, 1 or 2 associated arguments. If the
170// category is not enabled, then this does nothing.
oysteinedfcba472015-08-05 12:54:40 -0700171#define TRACE_EVENT_INSTANT0(category_group, name, scope) \
172 INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name, \
173 TRACE_EVENT_FLAG_NONE | scope)
Brian Osman594838a2017-07-21 08:57:53 -0400174
oysteinedfcba472015-08-05 12:54:40 -0700175#define TRACE_EVENT_INSTANT1(category_group, name, scope, arg1_name, arg1_val) \
176 INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name, \
177 TRACE_EVENT_FLAG_NONE | scope, arg1_name, arg1_val)
Brian Osman594838a2017-07-21 08:57:53 -0400178
oysteinedfcba472015-08-05 12:54:40 -0700179#define TRACE_EVENT_INSTANT2(category_group, name, scope, arg1_name, arg1_val, \
180 arg2_name, arg2_val) \
181 INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name, \
182 TRACE_EVENT_FLAG_NONE | scope, arg1_name, arg1_val, \
183 arg2_name, arg2_val)
oysteinedfcba472015-08-05 12:54:40 -0700184
oysteinedfcba472015-08-05 12:54:40 -0700185// Records the value of a counter called "name" immediately. Value
186// must be representable as a 32 bit integer.
oysteinedfcba472015-08-05 12:54:40 -0700187#define TRACE_COUNTER1(category_group, name, value) \
188 INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, category_group, name, \
189 TRACE_EVENT_FLAG_NONE, "value", \
190 static_cast<int>(value))
oysteinedfcba472015-08-05 12:54:40 -0700191
192// Records the values of a multi-parted counter called "name" immediately.
193// The UI will treat value1 and value2 as parts of a whole, displaying their
194// values as a stacked-bar chart.
oysteinedfcba472015-08-05 12:54:40 -0700195#define TRACE_COUNTER2(category_group, name, value1_name, value1_val, \
196 value2_name, value2_val) \
197 INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, category_group, name, \
198 TRACE_EVENT_FLAG_NONE, value1_name, \
199 static_cast<int>(value1_val), value2_name, \
200 static_cast<int>(value2_val))
oysteinedfcba472015-08-05 12:54:40 -0700201
Brian Osman1ba747a2018-04-27 10:31:58 -0400202#define TRACE_EVENT_ASYNC_BEGIN0(category, name, id) \
203 INTERNAL_TRACE_EVENT_ADD_WITH_ID( \
204 TRACE_EVENT_PHASE_ASYNC_BEGIN, category, name, id, TRACE_EVENT_FLAG_NONE)
205#define TRACE_EVENT_ASYNC_BEGIN1(category, name, id, arg1_name, arg1_val) \
206 INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
207 category, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
208#define TRACE_EVENT_ASYNC_BEGIN2(category, name, id, arg1_name, arg1_val, arg2_name, arg2_val) \
209 INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
210 category, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, arg2_name, arg2_val)
211
212#define TRACE_EVENT_ASYNC_END0(category, name, id) \
213 INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
214 category, name, id, TRACE_EVENT_FLAG_NONE)
215#define TRACE_EVENT_ASYNC_END1(category, name, id, arg1_name, arg1_val) \
216 INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
217 category, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
218#define TRACE_EVENT_ASYNC_END2(category, name, id, arg1_name, arg1_val, arg2_name, arg2_val) \
219 INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
220 category, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, arg2_name, arg2_val)
221
Brian Osmanb6705c22017-08-01 10:23:38 -0400222// Macros to track the life time and value of arbitrary client objects.
223#define TRACE_EVENT_OBJECT_CREATED_WITH_ID(category_group, name, id) \
224 INTERNAL_TRACE_EVENT_ADD_WITH_ID( \
225 TRACE_EVENT_PHASE_CREATE_OBJECT, category_group, name, id, \
226 TRACE_EVENT_FLAG_NONE)
227
228#define TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(category_group, name, id, \
229 snapshot) \
230 INTERNAL_TRACE_EVENT_ADD_WITH_ID( \
231 TRACE_EVENT_PHASE_SNAPSHOT_OBJECT, category_group, name, \
232 id, TRACE_EVENT_FLAG_NONE, "snapshot", snapshot)
233
234#define TRACE_EVENT_OBJECT_DELETED_WITH_ID(category_group, name, id) \
235 INTERNAL_TRACE_EVENT_ADD_WITH_ID( \
236 TRACE_EVENT_PHASE_DELETE_OBJECT, category_group, name, id, \
237 TRACE_EVENT_FLAG_NONE)
238
oysteinedfcba472015-08-05 12:54:40 -0700239// Macro to efficiently determine if a given category group is enabled.
240#define TRACE_EVENT_CATEGORY_GROUP_ENABLED(category_group, ret) \
241 do { \
242 INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \
243 if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \
244 *ret = true; \
245 } else { \
246 *ret = false; \
247 } \
248 } while (0)
249
Brian Osman26080be2017-08-11 09:53:35 -0400250#endif
oysteinedfcba472015-08-05 12:54:40 -0700251
oysteinedfcba472015-08-05 12:54:40 -0700252// Flags for changing the behavior of TRACE_EVENT_API_ADD_TRACE_EVENT.
253#define TRACE_EVENT_FLAG_NONE (static_cast<unsigned int>(0))
254#define TRACE_EVENT_FLAG_COPY (static_cast<unsigned int>(1 << 0))
255#define TRACE_EVENT_FLAG_HAS_ID (static_cast<unsigned int>(1 << 1))
256#define TRACE_EVENT_FLAG_MANGLE_ID (static_cast<unsigned int>(1 << 2))
257#define TRACE_EVENT_FLAG_SCOPE_OFFSET (static_cast<unsigned int>(1 << 3))
258#define TRACE_EVENT_FLAG_SCOPE_EXTRA (static_cast<unsigned int>(1 << 4))
259#define TRACE_EVENT_FLAG_EXPLICIT_TIMESTAMP (static_cast<unsigned int>(1 << 5))
260#define TRACE_EVENT_FLAG_ASYNC_TTS (static_cast<unsigned int>(1 << 6))
261#define TRACE_EVENT_FLAG_BIND_TO_ENCLOSING (static_cast<unsigned int>(1 << 7))
262#define TRACE_EVENT_FLAG_FLOW_IN (static_cast<unsigned int>(1 << 8))
263#define TRACE_EVENT_FLAG_FLOW_OUT (static_cast<unsigned int>(1 << 9))
264#define TRACE_EVENT_FLAG_HAS_CONTEXT_ID (static_cast<unsigned int>(1 << 10))
265
266#define TRACE_EVENT_FLAG_SCOPE_MASK \
267 (static_cast<unsigned int>(TRACE_EVENT_FLAG_SCOPE_OFFSET | \
268 TRACE_EVENT_FLAG_SCOPE_EXTRA))
269
270// Type values for identifying types in the TraceValue union.
271#define TRACE_VALUE_TYPE_BOOL (static_cast<unsigned char>(1))
272#define TRACE_VALUE_TYPE_UINT (static_cast<unsigned char>(2))
273#define TRACE_VALUE_TYPE_INT (static_cast<unsigned char>(3))
274#define TRACE_VALUE_TYPE_DOUBLE (static_cast<unsigned char>(4))
275#define TRACE_VALUE_TYPE_POINTER (static_cast<unsigned char>(5))
276#define TRACE_VALUE_TYPE_STRING (static_cast<unsigned char>(6))
277#define TRACE_VALUE_TYPE_COPY_STRING (static_cast<unsigned char>(7))
278#define TRACE_VALUE_TYPE_CONVERTABLE (static_cast<unsigned char>(8))
279
Brian Osman594838a2017-07-21 08:57:53 -0400280// Enum reflecting the scope of an INSTANT event. Must fit within TRACE_EVENT_FLAG_SCOPE_MASK.
oysteinedfcba472015-08-05 12:54:40 -0700281#define TRACE_EVENT_SCOPE_GLOBAL (static_cast<unsigned char>(0 << 3))
282#define TRACE_EVENT_SCOPE_PROCESS (static_cast<unsigned char>(1 << 3))
283#define TRACE_EVENT_SCOPE_THREAD (static_cast<unsigned char>(2 << 3))
284
285#define TRACE_EVENT_SCOPE_NAME_GLOBAL ('g')
286#define TRACE_EVENT_SCOPE_NAME_PROCESS ('p')
287#define TRACE_EVENT_SCOPE_NAME_THREAD ('t')
Brian Osman594838a2017-07-21 08:57:53 -0400288
Hal Canary03a7f5f2017-02-10 09:06:38 -0500289#endif // SkTraceEventCommon_DEFINED