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_DISABLE_TRACING 63 64 #define ATRACE_ANDROID_FRAMEWORK(fmt, ...) TRACE_EMPTY 65 #define ATRACE_ANDROID_FRAMEWORK_ALWAYS(fmt, ...) TRACE_EMPTY 66 #define TRACE_EVENT0(cg, n) TRACE_EMPTY 67 #define TRACE_EVENT0_ALWAYS(cg, n) TRACE_EMPTY 68 #define TRACE_EVENT1(cg, n, a1n, a1v) TRACE_EMPTY 69 #define TRACE_EVENT2(cg, n, a1n, a1v, a2n, a2v) TRACE_EMPTY 70 #define TRACE_EVENT_INSTANT0(cg, n, scope) TRACE_EMPTY 71 #define TRACE_EVENT_INSTANT1(cg, n, scope, a1n, a1v) TRACE_EMPTY 72 #define TRACE_EVENT_INSTANT2(cg, n, scope, a1n, a1v, a2n, a2v) TRACE_EMPTY 73 #define TRACE_COUNTER1(cg, n, value) TRACE_EMPTY 74 #define TRACE_COUNTER2(cg, n, v1n, v1v, v2n, v2v) TRACE_EMPTY 75 76 #elif defined(SK_BUILD_FOR_ANDROID_FRAMEWORK) 77 78 #include <cutils/trace.h> 79 #include <stdarg.h> 80 81 class SkAndroidFrameworkTraceUtil { 82 public: SkAndroidFrameworkTraceUtil(const char * name)83 SkAndroidFrameworkTraceUtil(const char* name) { 84 if (CC_UNLIKELY(gEnableAndroidTracing)) { 85 ATRACE_BEGIN(name); 86 } 87 } SkAndroidFrameworkTraceUtil(bool,const char * fmt,...)88 SkAndroidFrameworkTraceUtil(bool, const char* fmt, ...) { 89 if (CC_LIKELY((!gEnableAndroidTracing) || (!ATRACE_ENABLED()))) return; 90 91 const int BUFFER_SIZE = 256; 92 va_list ap; 93 char buf[BUFFER_SIZE]; 94 95 va_start(ap, fmt); 96 vsnprintf(buf, BUFFER_SIZE, fmt, ap); 97 va_end(ap); 98 99 ATRACE_BEGIN(buf); 100 } ~SkAndroidFrameworkTraceUtil()101 ~SkAndroidFrameworkTraceUtil() { 102 if (CC_UNLIKELY(gEnableAndroidTracing)) { 103 ATRACE_END(); 104 } 105 } 106 setEnableTracing(bool enableAndroidTracing)107 static void setEnableTracing(bool enableAndroidTracing) { 108 gEnableAndroidTracing = enableAndroidTracing; 109 } 110 getEnableTracing()111 static bool getEnableTracing() { 112 return gEnableAndroidTracing; 113 } 114 115 private: 116 static bool gEnableAndroidTracing; 117 }; 118 119 class SkAndroidFrameworkTraceUtilAlways { 120 public: SkAndroidFrameworkTraceUtilAlways(const char * name)121 SkAndroidFrameworkTraceUtilAlways(const char* name) { 122 ATRACE_BEGIN(name); 123 } 124 SkAndroidFrameworkTraceUtilAlways(bool,const char * fmt,...)125 SkAndroidFrameworkTraceUtilAlways(bool, const char* fmt, ...) { 126 if (!ATRACE_ENABLED()) return; 127 128 const int BUFFER_SIZE = 256; 129 va_list ap; 130 char buf[BUFFER_SIZE]; 131 132 va_start(ap, fmt); 133 vsnprintf(buf, BUFFER_SIZE, fmt, ap); 134 va_end(ap); 135 136 ATRACE_BEGIN(buf); 137 } ~SkAndroidFrameworkTraceUtilAlways()138 ~SkAndroidFrameworkTraceUtilAlways() { 139 ATRACE_END(); 140 } 141 }; 142 143 #define ATRACE_ANDROID_FRAMEWORK(fmt, ...) SkAndroidFrameworkTraceUtil __trace(true, fmt, ##__VA_ARGS__) 144 #define ATRACE_ANDROID_FRAMEWORK_ALWAYS(fmt, ...) SkAndroidFrameworkTraceUtilAlways __trace_always(true, fmt, ##__VA_ARGS__) 145 146 // Records a pair of begin and end events called "name" for the current scope, with 0, 1 or 2 147 // associated arguments. In the framework, the arguments are ignored. 148 #define TRACE_EVENT0(category_group, name) \ 149 SkAndroidFrameworkTraceUtil __trace(name) 150 #define TRACE_EVENT0_ALWAYS(category_group, name) \ 151 SkAndroidFrameworkTraceUtilAlways __trace_always(name) 152 #define TRACE_EVENT1(category_group, name, arg1_name, arg1_val) \ 153 SkAndroidFrameworkTraceUtil __trace(name) 154 #define TRACE_EVENT2(category_group, name, arg1_name, arg1_val, arg2_name, arg2_val) \ 155 SkAndroidFrameworkTraceUtil __trace(name) 156 157 // Records a single event called "name" immediately, with 0, 1 or 2 associated arguments. If the 158 // category is not enabled, then this does nothing. 159 #define TRACE_EVENT_INSTANT0(category_group, name, scope) \ 160 do { SkAndroidFrameworkTraceUtil __trace(name); } while(0) 161 162 #define TRACE_EVENT_INSTANT1(category_group, name, scope, arg1_name, arg1_val) \ 163 do { SkAndroidFrameworkTraceUtil __trace(name); } while(0) 164 165 #define TRACE_EVENT_INSTANT2(category_group, name, scope, arg1_name, arg1_val, \ 166 arg2_name, arg2_val) \ 167 do { SkAndroidFrameworkTraceUtil __trace(name); } while(0) 168 169 // Records the value of a counter called "name" immediately. Value 170 // must be representable as a 32 bit integer. 171 #define TRACE_COUNTER1(category_group, name, value) \ 172 if (CC_UNLIKELY(SkAndroidFrameworkTraceUtil::getEnableTracing())) { \ 173 ATRACE_INT(name, value); \ 174 } 175 176 // Records the values of a multi-parted counter called "name" immediately. 177 // In Chrome, this macro produces a stacked bar chart. ATrace doesn't support 178 // that, so this just produces two separate counters. 179 #define TRACE_COUNTER2(category_group, name, value1_name, value1_val, value2_name, value2_val) \ 180 do { \ 181 if (CC_UNLIKELY(SkAndroidFrameworkTraceUtil::getEnableTracing())) { \ 182 ATRACE_INT(name "-" value1_name, value1_val); \ 183 ATRACE_INT(name "-" value2_name, value2_val); \ 184 } \ 185 } while (0) 186 187 // ATrace has no object tracking 188 #define TRACE_EVENT_OBJECT_CREATED_WITH_ID(category_group, name, id) TRACE_EMPTY 189 #define TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(category_group, name, id, snapshot) TRACE_EMPTY 190 #define TRACE_EVENT_OBJECT_DELETED_WITH_ID(category_group, name, id) TRACE_EMPTY 191 192 // Macro to efficiently determine if a given category group is enabled. 193 // This is only used for some shader text logging that isn't supported in ATrace anyway. 194 #define TRACE_EVENT_CATEGORY_GROUP_ENABLED(category_group, ret) \ 195 do { *ret = false; } while (0) 196 197 #else // !SK_BUILD_FOR_ANDROID_FRAMEWORK && !SK_DISABLE_TRACING 198 199 #define ATRACE_ANDROID_FRAMEWORK(fmt, ...) TRACE_EMPTY 200 #define ATRACE_ANDROID_FRAMEWORK_ALWAYS(fmt, ...) TRACE_EMPTY 201 202 // Records a pair of begin and end events called "name" for the current scope, with 0, 1 or 2 203 // associated arguments. If the category is not enabled, then this does nothing. 204 #define TRACE_EVENT0(category_group, name) \ 205 INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name) 206 207 #define TRACE_EVENT0_ALWAYS(category_group, name) \ 208 INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name) 209 210 #define TRACE_EVENT1(category_group, name, arg1_name, arg1_val) \ 211 INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name, arg1_name, arg1_val) 212 213 #define TRACE_EVENT2(category_group, name, arg1_name, arg1_val, arg2_name, arg2_val) \ 214 INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name, arg1_name, arg1_val, arg2_name, arg2_val) 215 216 // Records a single event called "name" immediately, with 0, 1 or 2 associated arguments. If the 217 // category is not enabled, then this does nothing. 218 #define TRACE_EVENT_INSTANT0(category_group, name, scope) \ 219 INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name, \ 220 TRACE_EVENT_FLAG_NONE | scope) 221 222 #define TRACE_EVENT_INSTANT1(category_group, name, scope, arg1_name, arg1_val) \ 223 INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name, \ 224 TRACE_EVENT_FLAG_NONE | scope, arg1_name, arg1_val) 225 226 #define TRACE_EVENT_INSTANT2(category_group, name, scope, arg1_name, arg1_val, \ 227 arg2_name, arg2_val) \ 228 INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name, \ 229 TRACE_EVENT_FLAG_NONE | scope, arg1_name, arg1_val, \ 230 arg2_name, arg2_val) 231 232 // Records the value of a counter called "name" immediately. Value 233 // must be representable as a 32 bit integer. 234 #define TRACE_COUNTER1(category_group, name, value) \ 235 INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, category_group, name, \ 236 TRACE_EVENT_FLAG_NONE, "value", \ 237 static_cast<int>(value)) 238 239 // Records the values of a multi-parted counter called "name" immediately. 240 // The UI will treat value1 and value2 as parts of a whole, displaying their 241 // values as a stacked-bar chart. 242 #define TRACE_COUNTER2(category_group, name, value1_name, value1_val, \ 243 value2_name, value2_val) \ 244 INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, category_group, name, \ 245 TRACE_EVENT_FLAG_NONE, value1_name, \ 246 static_cast<int>(value1_val), value2_name, \ 247 static_cast<int>(value2_val)) 248 249 #define TRACE_EVENT_ASYNC_BEGIN0(category, name, id) \ 250 INTERNAL_TRACE_EVENT_ADD_WITH_ID( \ 251 TRACE_EVENT_PHASE_ASYNC_BEGIN, category, name, id, TRACE_EVENT_FLAG_NONE) 252 #define TRACE_EVENT_ASYNC_BEGIN1(category, name, id, arg1_name, arg1_val) \ 253 INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \ 254 category, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val) 255 #define TRACE_EVENT_ASYNC_BEGIN2(category, name, id, arg1_name, arg1_val, arg2_name, arg2_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, arg2_name, arg2_val) 258 259 #define TRACE_EVENT_ASYNC_END0(category, name, id) \ 260 INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \ 261 category, name, id, TRACE_EVENT_FLAG_NONE) 262 #define TRACE_EVENT_ASYNC_END1(category, name, id, arg1_name, arg1_val) \ 263 INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \ 264 category, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val) 265 #define TRACE_EVENT_ASYNC_END2(category, name, id, arg1_name, arg1_val, arg2_name, arg2_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, arg2_name, arg2_val) 268 269 // Macros to track the life time and value of arbitrary client objects. 270 #define TRACE_EVENT_OBJECT_CREATED_WITH_ID(category_group, name, id) \ 271 INTERNAL_TRACE_EVENT_ADD_WITH_ID( \ 272 TRACE_EVENT_PHASE_CREATE_OBJECT, category_group, name, id, \ 273 TRACE_EVENT_FLAG_NONE) 274 275 #define TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(category_group, name, id, \ 276 snapshot) \ 277 INTERNAL_TRACE_EVENT_ADD_WITH_ID( \ 278 TRACE_EVENT_PHASE_SNAPSHOT_OBJECT, category_group, name, \ 279 id, TRACE_EVENT_FLAG_NONE, "snapshot", snapshot) 280 281 #define TRACE_EVENT_OBJECT_DELETED_WITH_ID(category_group, name, id) \ 282 INTERNAL_TRACE_EVENT_ADD_WITH_ID( \ 283 TRACE_EVENT_PHASE_DELETE_OBJECT, category_group, name, id, \ 284 TRACE_EVENT_FLAG_NONE) 285 286 // Macro to efficiently determine if a given category group is enabled. 287 #define TRACE_EVENT_CATEGORY_GROUP_ENABLED(category_group, ret) \ 288 do { \ 289 INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \ 290 if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \ 291 *ret = true; \ 292 } else { \ 293 *ret = false; \ 294 } \ 295 } while (0) 296 297 #endif 298 299 // Flags for changing the behavior of TRACE_EVENT_API_ADD_TRACE_EVENT. 300 #define TRACE_EVENT_FLAG_NONE (static_cast<unsigned int>(0)) 301 #define TRACE_EVENT_FLAG_COPY (static_cast<unsigned int>(1 << 0)) 302 #define TRACE_EVENT_FLAG_HAS_ID (static_cast<unsigned int>(1 << 1)) 303 #define TRACE_EVENT_FLAG_MANGLE_ID (static_cast<unsigned int>(1 << 2)) 304 #define TRACE_EVENT_FLAG_SCOPE_OFFSET (static_cast<unsigned int>(1 << 3)) 305 #define TRACE_EVENT_FLAG_SCOPE_EXTRA (static_cast<unsigned int>(1 << 4)) 306 #define TRACE_EVENT_FLAG_EXPLICIT_TIMESTAMP (static_cast<unsigned int>(1 << 5)) 307 #define TRACE_EVENT_FLAG_ASYNC_TTS (static_cast<unsigned int>(1 << 6)) 308 #define TRACE_EVENT_FLAG_BIND_TO_ENCLOSING (static_cast<unsigned int>(1 << 7)) 309 #define TRACE_EVENT_FLAG_FLOW_IN (static_cast<unsigned int>(1 << 8)) 310 #define TRACE_EVENT_FLAG_FLOW_OUT (static_cast<unsigned int>(1 << 9)) 311 #define TRACE_EVENT_FLAG_HAS_CONTEXT_ID (static_cast<unsigned int>(1 << 10)) 312 313 #define TRACE_EVENT_FLAG_SCOPE_MASK \ 314 (static_cast<unsigned int>(TRACE_EVENT_FLAG_SCOPE_OFFSET | \ 315 TRACE_EVENT_FLAG_SCOPE_EXTRA)) 316 317 // Type values for identifying types in the TraceValue union. 318 #define TRACE_VALUE_TYPE_BOOL (static_cast<unsigned char>(1)) 319 #define TRACE_VALUE_TYPE_UINT (static_cast<unsigned char>(2)) 320 #define TRACE_VALUE_TYPE_INT (static_cast<unsigned char>(3)) 321 #define TRACE_VALUE_TYPE_DOUBLE (static_cast<unsigned char>(4)) 322 #define TRACE_VALUE_TYPE_POINTER (static_cast<unsigned char>(5)) 323 #define TRACE_VALUE_TYPE_STRING (static_cast<unsigned char>(6)) 324 #define TRACE_VALUE_TYPE_COPY_STRING (static_cast<unsigned char>(7)) 325 #define TRACE_VALUE_TYPE_CONVERTABLE (static_cast<unsigned char>(8)) 326 327 // Enum reflecting the scope of an INSTANT event. Must fit within TRACE_EVENT_FLAG_SCOPE_MASK. 328 #define TRACE_EVENT_SCOPE_GLOBAL (static_cast<unsigned char>(0 << 3)) 329 #define TRACE_EVENT_SCOPE_PROCESS (static_cast<unsigned char>(1 << 3)) 330 #define TRACE_EVENT_SCOPE_THREAD (static_cast<unsigned char>(2 << 3)) 331 332 #define TRACE_EVENT_SCOPE_NAME_GLOBAL ('g') 333 #define TRACE_EVENT_SCOPE_NAME_PROCESS ('p') 334 #define TRACE_EVENT_SCOPE_NAME_THREAD ('t') 335 336 #endif // SkTraceEventCommon_DEFINED 337