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