Home | History | Annotate | Download | only in core
      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 
     64     SkAndroidFrameworkTraceUtil(const char* name) {
     65         ATRACE_BEGIN(name);
     66     }
     67     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     }
     80     ~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