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