• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // --- Temporary Perfetto migration shim preamble ---
61 // Tracing in the Android framework, and tracing with Perfetto, are both in a partially migrated
62 // state (but fully functional).
63 //
64 // See go/skia-perfetto
65 //
66 // For Android framework:
67 // ---
68 // 1. If SK_ANDROID_FRAMEWORK_USE_PERFETTO is not defined, then all tracing macros map to no-ops.
69 // This is only relevant to host-mode builds, where ATrace isn't supported anyway, and tracing with
70 // Perfetto seems unnecessary. Note that SkAndroidFrameworkTraceUtil is still defined (assuming
71 // SK_BUILD_FOR_ANDROID_FRAMEWORK is defined) to support HWUI referencing it in host-mode builds.
72 //
73 // 2. If SK_ANDROID_FRAMEWORK_USE_PERFETTO *is* defined, then the tracing backend can be switched
74 // between ATrace and Perfetto at runtime. This is currently *only* supported in Android framework.
75 // SkAndroidFrameworkTraceUtil::setEnableTracing(bool) will still control broad tracing overall, but
76 // SkAndroidFrameworkTraceUtil::setUsePerfettoTrackEvents(bool) will now determine whether that
77 // tracing is done with ATrace (default/false) or Perfetto (true).
78 //
79 // Note: if setUsePerfettoTrackEvents(true) is called, then Perfetto will remain initialized until
80 // the process ends. This means some minimal state overhead will remain even after subseqently
81 // switching the process back to ATrace, but individual trace events will be correctly routed to
82 // whichever system is active in the moment. However, trace events which have begun but have not yet
83 // ended when a switch occurs will likely be corrupted. Thus, it's best to minimize the frequency of
84 // switching backend tracing systems at runtime.
85 //
86 // For Perfetto outside of Android framework (e.g. tools):
87 // ---
88 // SK_USE_PERFETTO (mutually exclusive with SK_ANDROID_FRAMEWORK_USE_PERFETTO) can be used to unlock
89 // SkPerfettoTrace, which can be used for in-process tracing via the standard Skia tracing flow of
90 // SkEventTracer::SetInstance(...). This is enabled in tools with the `--trace perfetto` argument.
91 // See https://skia.org/docs/dev/tools/tracing/#tracing-with-perfetto for more on SK_USE_PERFETTO.
92 
93 #ifdef SK_ANDROID_FRAMEWORK_USE_PERFETTO
94 
95 // PERFETTO_TRACK_EVENT_NAMESPACE must be defined before including Perfetto. This allows Skia to
96 // maintain separate "track event" category storage, etc. from codebases linked into the same
97 // executable, and avoid symbol duplication errors.
98 //
99 // NOTE: A side-effect of this is we must use skia::TrackEvent instead of perfetto::TrackEvent.
100 #define PERFETTO_TRACK_EVENT_NAMESPACE skia
101 #include <perfetto/tracing.h>
102 
103 #include <cutils/trace.h>
104 #include <stdarg.h>
105 #include <string_view>
106 
107 // WARNING: this list must be kept up to date with every category we use for tracing!
108 //
109 // When adding a new category it's likely best to add both "new_category" and "new_category.always",
110 // though not strictly required. "new_category.always" is used internally when "new_category" is
111 // given to TRACE_EVENTx_ALWAYS macros, which are used for core events that should always show up in
112 // traces for the Android framework. Adding both to begin with will likely reduce churn if/when
113 // "new_category" is used across both normal tracing macros and _ALWAYS variants in the future, but
114 // it's not a strict requirement.
115 //
116 // See stages section of go/skia-perfetto for timeline of when this should improve.
117 //
118 // TODO(b/262718654): make this compilation failure happen sooner than the Skia -> Android roll.
119 //
120 // Currently kept entirely separate from SkPerfettoTrace for simplicity, which uses dynamic
121 // categories and doesn't need these static category definitions.
122 PERFETTO_DEFINE_CATEGORIES(
123     perfetto::Category("GM"),
124     perfetto::Category("skia"),
125     perfetto::Category("skia.android"),
126     perfetto::Category("skia.gpu"),
127     perfetto::Category("skia.gpu.cache"),
128     perfetto::Category("skia.objects"),
129     perfetto::Category("skia.shaders"),
130     perfetto::Category("skottie"),
131     perfetto::Category("test"),
132     perfetto::Category("test_cpu"),
133     perfetto::Category("test_ganesh"),
134     perfetto::Category("test_graphite"),
135     // ".always" variants are currently required for any category used in TRACE_EVENTx_ALWAYS.
136     perfetto::Category("GM.always").SetTags("skia.always"),
137     perfetto::Category("skia.always").SetTags("skia.always"),
138     perfetto::Category("skia.android.always").SetTags("skia.always"),
139     perfetto::Category("skia.gpu.always").SetTags("skia.always"),
140     perfetto::Category("skia.gpu.cache.always").SetTags("skia.always"),
141     perfetto::Category("skia.objects.always").SetTags("skia.always"),
142     perfetto::Category("skia.shaders.always").SetTags("skia.always"),
143     perfetto::Category("skottie.always").SetTags("skia.always"),
144     perfetto::Category("test.always").SetTags("skia.always"),
145     perfetto::Category("test_cpu.always").SetTags("skia.always"),
146     perfetto::Category("test_ganesh.always").SetTags("skia.always"),
147     perfetto::Category("test_graphite.always").SetTags("skia.always"),
148 );
149 
150 #endif // SK_ANDROID_FRAMEWORK_USE_PERFETTO
151 
152 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
153 
154 #ifdef SK_DISABLE_TRACING
155 #error SK_DISABLE_TRACING and SK_BUILD_FOR_ANDROID_FRAMEWORK are mutually exclusive.
156 #endif // SK_DISABLE_TRACING [&& SK_BUILD_FOR_ANDROID_FRAMEWORK]
157 
158 #define SK_ANDROID_FRAMEWORK_ATRACE_BUFFER_SIZE 256
159 
160 class SkAndroidFrameworkTraceUtil {
161 public:
162     SkAndroidFrameworkTraceUtil() = delete;
163 
164     // Controls whether broad tracing is enabled. Warning: not thread-safe!
165     //
166     // Some key trace events may still be recorded when this is disabled, if a relevant tracing
167     // session is active.
168     //
169     // ATrace is used by default, but can be replaced with Perfetto by calling
170     // setUsePerfettoTrackEvents(true)
setEnableTracing(bool enableAndroidTracing)171     static void setEnableTracing(bool enableAndroidTracing) {
172         gEnableAndroidTracing = enableAndroidTracing;
173     }
174 
175     // Controls whether tracing uses Perfetto instead of ATrace. Warning: not thread-safe!
176     //
177     // Returns true if Skia was built with Perfetto, false otherwise.
setUsePerfettoTrackEvents(bool usePerfettoTrackEvents)178     static bool setUsePerfettoTrackEvents(bool usePerfettoTrackEvents) {
179 #ifdef SK_ANDROID_FRAMEWORK_USE_PERFETTO
180         // Ensure Perfetto is initialized if it wasn't already the preferred tracing backend.
181         if (!gUsePerfettoTrackEvents && usePerfettoTrackEvents) {
182             initPerfetto();
183         }
184         gUsePerfettoTrackEvents = usePerfettoTrackEvents;
185         return true;
186 #else // !SK_ANDROID_FRAMEWORK_USE_PERFETTO
187         // Note: please reach out to skia-android@google.com if you encounter this unexpectedly.
188         SkDebugf("Tracing Skia with Perfetto is not supported in this environment (host build?)");
189         return false;
190 #endif // SK_ANDROID_FRAMEWORK_USE_PERFETTO
191     }
192 
getEnableTracing()193     static bool getEnableTracing() {
194         return gEnableAndroidTracing;
195     }
196 
getUsePerfettoTrackEvents()197     static bool getUsePerfettoTrackEvents() {
198         return gUsePerfettoTrackEvents;
199     }
200 
201 private:
202     static bool gEnableAndroidTracing;
203     static bool gUsePerfettoTrackEvents;
204 
205 #ifdef SK_ANDROID_FRAMEWORK_USE_PERFETTO
206     // Initializes tracing systems, and establishes a connection to the 'traced' daemon.
207     //
208     // Can be called multiple times.
initPerfetto()209     static void initPerfetto() {
210         ::perfetto::TracingInitArgs perfettoArgs;
211         perfettoArgs.backends |= perfetto::kSystemBackend;
212         ::perfetto::Tracing::Initialize(perfettoArgs);
213         ::skia::TrackEvent::Register();
214     }
215 #endif // SK_ANDROID_FRAMEWORK_USE_PERFETTO
216 };
217 #endif // SK_BUILD_FOR_ANDROID_FRAMEWORK
218 
219 #ifdef SK_DEBUG
220 static void skprintf_like_noop(const char format[], ...) SK_PRINTF_LIKE(1, 2);
skprintf_like_noop(const char format[],...)221 static inline void skprintf_like_noop(const char format[], ...) {}
222 template <typename... Args>
sk_noop(Args...)223 static inline void sk_noop(Args...) {}
224 #define TRACE_EMPTY(...) do { sk_noop(__VA_ARGS__); } while (0)
225 #define TRACE_EMPTY_FMT(fmt, ...) do { skprintf_like_noop(fmt, ##__VA_ARGS__); } while (0)
226 #else
227 #define TRACE_EMPTY(...) do {} while (0)
228 #define TRACE_EMPTY_FMT(fmt, ...) do {} while (0)
229 #endif
230 
231 #if defined(SK_DISABLE_TRACING) || \
232         (defined(SK_BUILD_FOR_ANDROID_FRAMEWORK) && !defined(SK_ANDROID_FRAMEWORK_USE_PERFETTO))
233 
234     #define ATRACE_ANDROID_FRAMEWORK(fmt, ...) TRACE_EMPTY_FMT(fmt, ##__VA_ARGS__)
235     #define ATRACE_ANDROID_FRAMEWORK_ALWAYS(fmt, ...) TRACE_EMPTY_FMT(fmt, ##__VA_ARGS__)
236     #define TRACE_EVENT0(cg, n) TRACE_EMPTY(cg, n)
237     #define TRACE_EVENT1(cg, n, a1n, a1v) TRACE_EMPTY(cg, n, a1n, a1v)
238     #define TRACE_EVENT2(cg, n, a1n, a1v, a2n, a2v) TRACE_EMPTY(cg, n, a1n, a1v, a2n, a2v)
239     #define TRACE_EVENT0_ALWAYS(cg, n) TRACE_EMPTY(cg, n)
240     #define TRACE_EVENT1_ALWAYS(cg, n, a1n, a1v) TRACE_EMPTY(cg, n, a1n, a1v)
241     #define TRACE_EVENT2_ALWAYS(cg, n, a1n, a1v, a2n, a2v) TRACE_EMPTY(cg, n, a1n, a1v, a2n, a2v)
242     #define TRACE_EVENT_INSTANT0(cg, n, scope) TRACE_EMPTY(cg, n, scope)
243     #define TRACE_EVENT_INSTANT1(cg, n, scope, a1n, a1v) TRACE_EMPTY(cg, n, scope, a1n, a1v)
244     #define TRACE_EVENT_INSTANT2(cg, n, scope, a1n, a1v, a2n, a2v)  \
245         TRACE_EMPTY(cg, n, scope, a1n, a1v, a2n, a2v)
246     #define TRACE_EVENT_OBJECT_CREATED_WITH_ID(cg, n, id) TRACE_EMPTY(cg, n, id)
247     #define TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(cg, n, id, ss) TRACE_EMPTY(cg, n, id, ss)
248     #define TRACE_EVENT_OBJECT_DELETED_WITH_ID(cg, n, id) TRACE_EMPTY(cg, n, id)
249     #define TRACE_COUNTER1(cg, n, value) TRACE_EMPTY(cg, n, value)
250     #define TRACE_COUNTER2(cg, n, v1n, v1v, v2n, v2v) TRACE_EMPTY(cg, n, v1n, v1v, v2n, v2v)
251 
252 #elif defined(SK_ANDROID_FRAMEWORK_USE_PERFETTO)
253 
254 namespace skia_private {
255     // ATrace can't accept ::perfetto::DynamicString or ::perfetto::StaticString, so any trace event
256     // names that were wrapped in TRACE_STR_COPY or TRACE_STR_STATIC need to be unboxed back to
257     // char* before being passed to ATrace.
UnboxPerfettoString(const::perfetto::DynamicString & str)258     inline const char* UnboxPerfettoString(const ::perfetto::DynamicString& str) {
259         return str.value;
260     }
UnboxPerfettoString(const::perfetto::StaticString & str)261     inline const char* UnboxPerfettoString(const ::perfetto::StaticString& str) {
262         return str.value;
263     }
UnboxPerfettoString(const char * str)264     inline const char* UnboxPerfettoString(const char* str) {
265         return str;
266     }
267 
268     // WrapTraceArgInStdString serves a similar purpose to UnboxPerfettoString, but also accepts
269     // numeric values that are often used as trace arguments. This necessitates always wrapping the
270     // argument in a new std::string, instead of just passing along/unboxing an existing C-style
271     // string. This comes at a slight cost, and should only be used for trace slice arguments but
272     // not slice names, where UnboxPerfettoString should be used instead.
273     template<typename T>
WrapTraceArgInStdString(const T numeric)274     inline std::string WrapTraceArgInStdString(const T numeric) {
275         return std::to_string(numeric);
276     }
WrapTraceArgInStdString(const::perfetto::DynamicString & str)277     inline std::string WrapTraceArgInStdString(const ::perfetto::DynamicString& str) {
278         return std::string(str.value);
279     }
WrapTraceArgInStdString(const::perfetto::StaticString & str)280     inline std::string WrapTraceArgInStdString(const ::perfetto::StaticString& str) {
281         return std::string(str.value);
282     }
WrapTraceArgInStdString(const char * str)283     inline std::string WrapTraceArgInStdString(const char* str) {
284         return std::string(str);
285     }
286 
StrEndsWithAndLongerThan(const char * str,const char * suffix)287     constexpr bool StrEndsWithAndLongerThan(const char* str, const char* suffix) {
288         auto strView = std::basic_string_view(str);
289         auto suffixView = std::basic_string_view(suffix);
290         // string_view::ends_with isn't available until C++20
291         return strView.size() > suffixView.size() &&
292                 strView.compare(strView.size() - suffixView.size(),
293                                 std::string_view::npos, suffixView) == 0;
294     }
295 }
296 
297 // Generate a unique variable name with a given prefix.
298 // The indirection in this multi-level macro lets __LINE__ expand at the right time/place to get
299 // prefix123 instead of prefix__LINE__.
300 #define SK_PERFETTO_INTERNAL_CONCAT2(a, b) a##b
301 #define SK_PERFETTO_INTERNAL_CONCAT(a, b) SK_PERFETTO_INTERNAL_CONCAT2(a, b)
302 #define SK_PERFETTO_UID(prefix) SK_PERFETTO_INTERNAL_CONCAT(prefix, __LINE__)
303 
304 // Used by SK_INTERNAL_ATRACE_ARGS_BEGIN and SK_INTERNAL_ATRACE_ARGS_END to select which overloaded
305 // macro to use depending on how many __VA_ARGS__ are present. The number of __VA_ARGS__ piped in
306 // from this macro caller's parent caller determines which macro name given by the caller ends up in
307 // the macro_name slot here. See usage for nuance.
308 #define SK_INTERNAL_GET_ATRACE_ARGS_MACRO(_0, _1a, _1b, _2a, _2b, macro_name, ...) macro_name
309 
310 #define SK_INTERNAL_ATRACE_ARGS_BEGIN_0(name) \
311     ATRACE_BEGIN(::skia_private::UnboxPerfettoString(name));
312 
313 #define SK_INTERNAL_ATRACE_ARGS_BEGIN_1(name, arg1_name, arg1_val)                 \
314     char SK_PERFETTO_UID(skTraceStrBuf1)[SK_ANDROID_FRAMEWORK_ATRACE_BUFFER_SIZE]; \
315     snprintf(SK_PERFETTO_UID(skTraceStrBuf1),                                      \
316              SK_ANDROID_FRAMEWORK_ATRACE_BUFFER_SIZE,                              \
317              "^(%s: %s)",                                                          \
318              ::skia_private::UnboxPerfettoString(arg1_name),                       \
319              ::skia_private::WrapTraceArgInStdString(arg1_val).c_str());           \
320     ATRACE_BEGIN(::skia_private::UnboxPerfettoString(name));                       \
321     ATRACE_BEGIN(SK_PERFETTO_UID(skTraceStrBuf1));
322 
323 #define SK_INTERNAL_ATRACE_ARGS_BEGIN_2(                                           \
324         name, arg1_name, arg1_val, arg2_name, arg2_val, ...)                       \
325     char SK_PERFETTO_UID(skTraceStrBuf1)[SK_ANDROID_FRAMEWORK_ATRACE_BUFFER_SIZE]; \
326     char SK_PERFETTO_UID(skTraceStrBuf2)[SK_ANDROID_FRAMEWORK_ATRACE_BUFFER_SIZE]; \
327     snprintf(SK_PERFETTO_UID(skTraceStrBuf1),                                      \
328              SK_ANDROID_FRAMEWORK_ATRACE_BUFFER_SIZE,                              \
329              "^(%s: %s)",                                                          \
330              ::skia_private::UnboxPerfettoString(arg1_name),                       \
331              ::skia_private::WrapTraceArgInStdString(arg1_val).c_str());           \
332     snprintf(SK_PERFETTO_UID(skTraceStrBuf2),                                      \
333              SK_ANDROID_FRAMEWORK_ATRACE_BUFFER_SIZE,                              \
334             "^(%s: %s)",                                                           \
335              ::skia_private::UnboxPerfettoString(arg2_name),                       \
336              ::skia_private::WrapTraceArgInStdString(arg2_val).c_str());           \
337     ATRACE_BEGIN(::skia_private::UnboxPerfettoString(name));                       \
338     ATRACE_BEGIN(SK_PERFETTO_UID(skTraceStrBuf1));                                 \
339     ATRACE_BEGIN(SK_PERFETTO_UID(skTraceStrBuf2));
340 
341 // Will map to either the 0, 1, or 2 argument variant of this macro, which will trigger an
342 // ATRACE_BEGIN event for the slice name, and one for each argument <name, value> pair. The caller
343 // must ensure each of these 1-3 slices are properly terminated with 1-3 matching ATRACE_END events.
344 #define SK_INTERNAL_ATRACE_ARGS_BEGIN(slice_name, ...)                 \
345     SK_INTERNAL_GET_ATRACE_ARGS_MACRO(0,                               \
346                                       ##__VA_ARGS__,                   \
347                                       SK_INTERNAL_ATRACE_ARGS_BEGIN_2, \
348                                       0,                               \
349                                       SK_INTERNAL_ATRACE_ARGS_BEGIN_1, \
350                                       0,                               \
351                                       SK_INTERNAL_ATRACE_ARGS_BEGIN_0) \
352     (slice_name, ##__VA_ARGS__)
353 
354 #define SK_INTERNAL_ATRACE_ARGS_END_2(arg1_name, arg1_val, arg2_name, arg2_val, ...) \
355     ATRACE_END();                                                                    \
356     ATRACE_END();                                                                    \
357     ATRACE_END();
358 
359 #define SK_INTERNAL_ATRACE_ARGS_END_1(arg1_name, arg1_val) \
360     ATRACE_END();                                          \
361     ATRACE_END();
362 
363 #define SK_INTERNAL_ATRACE_ARGS_END_0() \
364     ATRACE_END();
365 
366 // Will map to either the 0, 1, or 2 argument variant of this macro, which will trigger an
367 // ATRACE_END event for the slice name, and one for each argument <name, value> pair. The caller
368 // must ensure each of these 1-3 slices already existed from 1-3 matching ATRACE_BEGIN events.
369 #define SK_INTERNAL_ATRACE_ARGS_END(...)                             \
370     SK_INTERNAL_GET_ATRACE_ARGS_MACRO(0,                             \
371                                       ##__VA_ARGS__,                 \
372                                       SK_INTERNAL_ATRACE_ARGS_END_2, \
373                                       0,                             \
374                                       SK_INTERNAL_ATRACE_ARGS_END_1, \
375                                       0,                             \
376                                       SK_INTERNAL_ATRACE_ARGS_END_0) \
377     (__VA_ARGS__)
378 
379 // Assuming there is an active tracing session, this call will create a trace event if tracing is
380 // enabled (with SkAndroidFrameworkTraceUtil::setEnableTracing(true)) or if force_always_trace is
381 // true. The event goes through ATrace by default, but can be routed to Perfetto instead by calling
382 // SkAndroidFrameworkTraceUtil::setUsePerfettoTrackEvents(true).
383 //
384 // If ATrace is used, then additional sub-events will be created for each trace event argument
385 // <name, value> pair (up to a max of two argument pairs). If Perfetto is used, then any arguments
386 // will be associated with a single event.
387 //
388 // If force_always_trace = true, then the caller *must* append the ".always" suffix to the provided
389 // category. This allows Perfetto tracing sessions to optionally filter to just the "skia.always"
390 // category tag. This requirement is enforced at compile time.
391 #define TRACE_EVENT_ATRACE_OR_PERFETTO_FORCEABLE(force_always_trace, category, name, ...)       \
392     struct SK_PERFETTO_UID(ScopedEvent) {                                                       \
393         struct EventFinalizer {                                                                 \
394             /* The ... parameter slot is an implementation detail. It allows the */             \
395             /* anonymous struct to use aggregate initialization to invoke the    */             \
396             /* lambda (which emits the BEGIN event and returns an integer)       */             \
397             /* with the proper reference capture for any                         */             \
398             /* TrackEventArgumentFunction in |__VA_ARGS__|. This is required so  */             \
399             /* that the scoped event is exactly ONE line and can't escape the    */             \
400             /* scope if used in a single line if statement.                      */             \
401             EventFinalizer(...) {}                                                              \
402             ~EventFinalizer() {                                                                 \
403                 if (force_always_trace ||                                                       \
404                         CC_UNLIKELY(SkAndroidFrameworkTraceUtil::getEnableTracing())) {         \
405                     if (SkAndroidFrameworkTraceUtil::getUsePerfettoTrackEvents()) {             \
406                         TRACE_EVENT_END(category);                                              \
407                     } else {                                                                    \
408                         SK_INTERNAL_ATRACE_ARGS_END(__VA_ARGS__);                               \
409                     }                                                                           \
410                 }                                                                               \
411             }                                                                                   \
412                                                                                                 \
413             EventFinalizer(const EventFinalizer&) = delete;                                     \
414             EventFinalizer& operator=(const EventFinalizer&) = delete;                          \
415                                                                                                 \
416             EventFinalizer(EventFinalizer&&) = default;                                         \
417             EventFinalizer& operator=(EventFinalizer&&) = delete;                               \
418         } finalizer;                                                                            \
419     } SK_PERFETTO_UID(scoped_event) {                                                           \
420         [&]() {                                                                                 \
421             static_assert(!force_always_trace ||                                                \
422                         ::skia_private::StrEndsWithAndLongerThan(category, ".always"),          \
423                     "[force_always_trace == true] requires [category] to end in '.always'");    \
424             if (force_always_trace ||                                                           \
425                     CC_UNLIKELY(SkAndroidFrameworkTraceUtil::getEnableTracing())) {             \
426                 if (SkAndroidFrameworkTraceUtil::getUsePerfettoTrackEvents()) {                 \
427                     TRACE_EVENT_BEGIN(category, name, ##__VA_ARGS__);                           \
428                 } else {                                                                        \
429                     SK_INTERNAL_ATRACE_ARGS_BEGIN(name, ##__VA_ARGS__);                         \
430                 }                                                                               \
431             }                                                                                   \
432             return 0;                                                                           \
433         }()                                                                                     \
434     }
435 
436 // Records an event with the current tracing backend if overall tracing is enabled, and Skia's
437 // "broad" tracing is enabled with SkAndroidFrameworkTraceUtil::setEnableTracing(true).
438 #define TRACE_EVENT_ATRACE_OR_PERFETTO(category, name, ...)                     \
439     TRACE_EVENT_ATRACE_OR_PERFETTO_FORCEABLE(                                   \
440             /* force_always_trace = */ false, category, name, ##__VA_ARGS__)
441 
442 // Traces a formatted string if overall tracing is enabled, and Skia's "broad" tracing is enabled
443 // with SkAndroidFrameworkTraceUtil::setEnableTracing(true).
444 // No-op outside of Android framework builds.
445 // WARNING: this macro expands to a multi-line statement, and must not be used in a single line
446 // control statement!
447 #define ATRACE_ANDROID_FRAMEWORK(fmt, ...)                                                  \
448     char SK_PERFETTO_UID(skTraceStrBuf)[SK_ANDROID_FRAMEWORK_ATRACE_BUFFER_SIZE];           \
449     if (SkAndroidFrameworkTraceUtil::getEnableTracing()) {                                  \
450         snprintf(SK_PERFETTO_UID(skTraceStrBuf), SK_ANDROID_FRAMEWORK_ATRACE_BUFFER_SIZE,   \
451                  fmt, ##__VA_ARGS__);                                                       \
452     }                                                                                       \
453     TRACE_EVENT0("skia.android", TRACE_STR_COPY(SK_PERFETTO_UID(skTraceStrBuf)))
454 
455 // Traces a formatted string as long as overall tracing is enabled, even if Skia's "broad" tracing
456 // is disabled.
457 // No-op outside of Android framework builds.
458 // WARNING: this macro expands to a multi-line statement, and must not be used in a single line
459 // control statement!
460 #define ATRACE_ANDROID_FRAMEWORK_ALWAYS(fmt, ...)                                           \
461     char SK_PERFETTO_UID(skTraceStrBuf)[SK_ANDROID_FRAMEWORK_ATRACE_BUFFER_SIZE];           \
462     snprintf(SK_PERFETTO_UID(skTraceStrBuf), SK_ANDROID_FRAMEWORK_ATRACE_BUFFER_SIZE,       \
463              fmt, ##__VA_ARGS__);                                                           \
464     TRACE_EVENT0_ALWAYS("skia.android", TRACE_STR_COPY(SK_PERFETTO_UID(skTraceStrBuf)))
465 
466 // Records a pair of begin and end events called "name" (with 0-2 associated arguments) for the
467 // current scope as long as overall tracing is enabled, and Skia's "broad" tracing is enabled with
468 // SkAndroidFrameworkTraceUtil::setEnableTracing(true).
469 // Note that ATrace does not natively support trace arguments, so arguments are recorded as separate
470 // sub-events when ATrace is set as the current tracing backend. The Perfetto tracing backend
471 // associates any arguments with a single event / slice.
472 #define TRACE_EVENT0(category_group, name) \
473     TRACE_EVENT_ATRACE_OR_PERFETTO(category_group, name)
474 #define TRACE_EVENT1(category_group, name, arg1_name, arg1_val) \
475     TRACE_EVENT_ATRACE_OR_PERFETTO(category_group, name, arg1_name, arg1_val)
476 #define TRACE_EVENT2(category_group, name, arg1_name, arg1_val, arg2_name, arg2_val) \
477     TRACE_EVENT_ATRACE_OR_PERFETTO(category_group, name, arg1_name, arg1_val, arg2_name, arg2_val)
478 
479 // Records a pair of begin and end events called "name" (with 0-2 associated arguments) for the
480 // current scope as long as overall tracing is enabled, even if Skia's "broad" tracing is disabled.
481 // Note that ATrace does not natively support trace arguments, so arguments are recorded as separate
482 // sub-events when ATrace is set as the current tracing backend. The Perfetto tracing backend
483 // associates any arguments with a single event / slice.
484 // Note: the ".always" suffix is appended to category_group in _ALWAYS trace event macro variants.
485 #define TRACE_EVENT0_ALWAYS(category_group, name) \
486     TRACE_EVENT_ATRACE_OR_PERFETTO_FORCEABLE(     \
487             /* force_always_trace = */ true, category_group ".always", name)
488 #define TRACE_EVENT1_ALWAYS(category_group, name, arg1_name, arg1_val) \
489     TRACE_EVENT_ATRACE_OR_PERFETTO_FORCEABLE(                          \
490             /* force_always_trace = */ true, category_group ".always", name, arg1_name, arg1_val)
491 #define TRACE_EVENT2_ALWAYS(category_group, name, arg1_name, arg1_val, arg2_name, arg2_val) \
492     TRACE_EVENT_ATRACE_OR_PERFETTO_FORCEABLE(/* force_always_trace = */ true,               \
493                                              category_group ".always",                      \
494                                              name,                                          \
495                                              arg1_name,                                     \
496                                              arg1_val,                                      \
497                                              arg2_name,                                     \
498                                              arg2_val)
499 
500 // Records a single event called "name" immediately, with 0, 1 or 2 associated arguments.
501 // Note that ATrace does not support trace arguments, so they are only recorded when Perfetto is set
502 // as the current tracing backend.
503 #define TRACE_EVENT_INSTANT0(category_group, name, scope) \
504     do { TRACE_EVENT_ATRACE_OR_PERFETTO(category_group, name); } while(0)
505 
506 #define TRACE_EVENT_INSTANT1(category_group, name, scope, arg1_name, arg1_val) \
507     do { TRACE_EVENT_ATRACE_OR_PERFETTO(category_group, name, arg1_name, arg1_val); } while(0)
508 
509 #define TRACE_EVENT_INSTANT2(category_group, name, scope, arg1_name, arg1_val,      \
510                              arg2_name, arg2_val)                                   \
511     do { TRACE_EVENT_ATRACE_OR_PERFETTO(category_group, name, arg1_name, arg1_val,  \
512                                         arg2_name, arg2_val); } while(0)
513 
514 // Records the value of a counter called "name" immediately. Value
515 // must be representable as a 32 bit integer.
516 #define TRACE_COUNTER1(category_group, name, value)                     \
517     if (CC_UNLIKELY(SkAndroidFrameworkTraceUtil::getEnableTracing())) { \
518         if (SkAndroidFrameworkTraceUtil::getUsePerfettoTrackEvents()) { \
519             TRACE_COUNTER(category_group, name, value);                 \
520         } else {                                                        \
521             ATRACE_INT(name, value);                                    \
522         }                                                               \
523     }
524 
525 // Records the values of a multi-parted counter called "name" immediately.
526 // In Chrome, this macro produces a stacked bar chart. Perfetto doesn't support
527 // that (related: b/242349575), so this just produces two separate counters.
528 #define TRACE_COUNTER2(category_group, name, value1_name, value1_val, value2_name, value2_val)  \
529     if (CC_UNLIKELY(SkAndroidFrameworkTraceUtil::getEnableTracing())) {                         \
530         if (SkAndroidFrameworkTraceUtil::getUsePerfettoTrackEvents()) {                         \
531             TRACE_COUNTER(category_group, name "-" value1_name, value1_val);                    \
532             TRACE_COUNTER(category_group, name "-" value2_name, value2_val);                    \
533         } else {                                                                                \
534             ATRACE_INT(name "-" value1_name, value1_val);                                       \
535             ATRACE_INT(name "-" value2_name, value2_val);                                       \
536         }                                                                                       \
537     }
538 
539 // ATrace has no object tracking, and would require a legacy shim for Perfetto (which likely no-ops
540 // here). Further, these don't appear to currently be used outside of tests.
541 #define TRACE_EVENT_OBJECT_CREATED_WITH_ID(category_group, name, id) \
542     TRACE_EMPTY(category_group, name, id)
543 #define TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(category_group, name, id, snapshot) \
544     TRACE_EMPTY(category_group, name, id, snapshot)
545 #define TRACE_EVENT_OBJECT_DELETED_WITH_ID(category_group, name, id) \
546     TRACE_EMPTY(category_group, name, id)
547 
548 // Macro to efficiently determine if a given category group is enabled. Only works with Perfetto.
549 // This is only used for some shader text logging that isn't supported in ATrace anyway.
550 #define TRACE_EVENT_CATEGORY_GROUP_ENABLED(category_group, ret)                     \
551     if (CC_UNLIKELY(SkAndroidFrameworkTraceUtil::getEnableTracing() &&              \
552                     SkAndroidFrameworkTraceUtil::getUsePerfettoTrackEvents)) {      \
553         *ret = TRACE_EVENT_CATEGORY_ENABLED(category_group);                        \
554     } else {                                                                        \
555         *ret = false;                                                               \
556     }
557 
558 #else // Route through SkEventTracer (!SK_DISABLE_TRACING && !SK_ANDROID_FRAMEWORK_USE_PERFETTO)
559 
560 #define ATRACE_ANDROID_FRAMEWORK(fmt, ...) TRACE_EMPTY_FMT(fmt, ##__VA_ARGS__)
561 #define ATRACE_ANDROID_FRAMEWORK_ALWAYS(fmt, ...) TRACE_EMPTY_FMT(fmt, ##__VA_ARGS__)
562 
563 // Records a pair of begin and end events called "name" for the current scope, with 0, 1 or 2
564 // associated arguments. If the category is not enabled, then this does nothing.
565 #define TRACE_EVENT0(category_group, name) \
566   INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name)
567 
568 #define TRACE_EVENT1(category_group, name, arg1_name, arg1_val) \
569   INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name, arg1_name, arg1_val)
570 
571 #define TRACE_EVENT2(category_group, name, arg1_name, arg1_val, arg2_name, arg2_val) \
572   INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name, arg1_name, arg1_val, arg2_name, arg2_val)
573 
574 #define TRACE_EVENT0_ALWAYS(category_group, name) \
575   INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name)
576 
577 #define TRACE_EVENT1_ALWAYS(category_group, name, arg1_name, arg1_val) \
578   INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name, arg1_name, arg1_val)
579 
580 #define TRACE_EVENT2_ALWAYS(category_group, name, arg1_name, arg1_val, arg2_name, arg2_val) \
581   INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name, arg1_name, arg1_val, arg2_name, arg2_val)
582 
583 // Records a single event called "name" immediately, with 0, 1 or 2 associated arguments. If the
584 // category is not enabled, then this does nothing.
585 #define TRACE_EVENT_INSTANT0(category_group, name, scope)                   \
586   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name, \
587                            TRACE_EVENT_FLAG_NONE | scope)
588 
589 #define TRACE_EVENT_INSTANT1(category_group, name, scope, arg1_name, arg1_val) \
590   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name,    \
591                            TRACE_EVENT_FLAG_NONE | scope, arg1_name, arg1_val)
592 
593 #define TRACE_EVENT_INSTANT2(category_group, name, scope, arg1_name, arg1_val, \
594                              arg2_name, arg2_val)                              \
595   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name,    \
596                            TRACE_EVENT_FLAG_NONE | scope, arg1_name, arg1_val, \
597                            arg2_name, arg2_val)
598 
599 // Records the value of a counter called "name" immediately. Value
600 // must be representable as a 32 bit integer.
601 #define TRACE_COUNTER1(category_group, name, value)                         \
602   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, category_group, name, \
603                            TRACE_EVENT_FLAG_NONE, "value",                  \
604                            static_cast<int>(value))
605 
606 // Records the values of a multi-parted counter called "name" immediately.
607 // The UI will treat value1 and value2 as parts of a whole, displaying their
608 // values as a stacked-bar chart.
609 #define TRACE_COUNTER2(category_group, name, value1_name, value1_val,       \
610                        value2_name, value2_val)                             \
611   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, category_group, name, \
612                            TRACE_EVENT_FLAG_NONE, value1_name,              \
613                            static_cast<int>(value1_val), value2_name,       \
614                            static_cast<int>(value2_val))
615 
616 #define TRACE_EVENT_ASYNC_BEGIN0(category, name, id)                                           \
617     INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                                          \
618         TRACE_EVENT_PHASE_ASYNC_BEGIN, category, name, id, TRACE_EVENT_FLAG_NONE)
619 #define TRACE_EVENT_ASYNC_BEGIN1(category, name, id, arg1_name, arg1_val)                      \
620     INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN,                            \
621         category, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
622 #define TRACE_EVENT_ASYNC_BEGIN2(category, name, id, arg1_name, arg1_val, arg2_name, arg2_val) \
623     INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN,                            \
624         category, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, arg2_name, arg2_val)
625 
626 #define TRACE_EVENT_ASYNC_END0(category, name, id)                                           \
627     INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END,                            \
628         category, name, id, TRACE_EVENT_FLAG_NONE)
629 #define TRACE_EVENT_ASYNC_END1(category, name, id, arg1_name, arg1_val)                      \
630     INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END,                            \
631         category, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
632 #define TRACE_EVENT_ASYNC_END2(category, name, id, arg1_name, arg1_val, arg2_name, arg2_val) \
633     INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END,                            \
634         category, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, arg2_name, arg2_val)
635 
636 // Macros to track the life time and value of arbitrary client objects.
637 #define TRACE_EVENT_OBJECT_CREATED_WITH_ID(category_group, name, id) \
638   INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                  \
639       TRACE_EVENT_PHASE_CREATE_OBJECT, category_group, name, id,     \
640       TRACE_EVENT_FLAG_NONE)
641 
642 #define TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(category_group, name, id, \
643                                             snapshot)                 \
644   INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                   \
645       TRACE_EVENT_PHASE_SNAPSHOT_OBJECT, category_group, name,        \
646       id, TRACE_EVENT_FLAG_NONE, "snapshot", snapshot)
647 
648 #define TRACE_EVENT_OBJECT_DELETED_WITH_ID(category_group, name, id) \
649   INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                  \
650       TRACE_EVENT_PHASE_DELETE_OBJECT, category_group, name, id,     \
651       TRACE_EVENT_FLAG_NONE)
652 
653 // Macro to efficiently determine if a given category group is enabled.
654 #define TRACE_EVENT_CATEGORY_GROUP_ENABLED(category_group, ret)             \
655   do {                                                                      \
656     INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group);                 \
657     if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \
658       *ret = true;                                                          \
659     } else {                                                                \
660       *ret = false;                                                         \
661     }                                                                       \
662   } while (0)
663 
664 #endif
665 
666 // Flags for changing the behavior of TRACE_EVENT_API_ADD_TRACE_EVENT.
667 #define TRACE_EVENT_FLAG_NONE (static_cast<unsigned int>(0))
668 #define TRACE_EVENT_FLAG_COPY (static_cast<unsigned int>(1 << 0))
669 #define TRACE_EVENT_FLAG_HAS_ID (static_cast<unsigned int>(1 << 1))
670 #define TRACE_EVENT_FLAG_MANGLE_ID (static_cast<unsigned int>(1 << 2))
671 #define TRACE_EVENT_FLAG_SCOPE_OFFSET (static_cast<unsigned int>(1 << 3))
672 #define TRACE_EVENT_FLAG_SCOPE_EXTRA (static_cast<unsigned int>(1 << 4))
673 #define TRACE_EVENT_FLAG_EXPLICIT_TIMESTAMP (static_cast<unsigned int>(1 << 5))
674 #define TRACE_EVENT_FLAG_ASYNC_TTS (static_cast<unsigned int>(1 << 6))
675 #define TRACE_EVENT_FLAG_BIND_TO_ENCLOSING (static_cast<unsigned int>(1 << 7))
676 #define TRACE_EVENT_FLAG_FLOW_IN (static_cast<unsigned int>(1 << 8))
677 #define TRACE_EVENT_FLAG_FLOW_OUT (static_cast<unsigned int>(1 << 9))
678 #define TRACE_EVENT_FLAG_HAS_CONTEXT_ID (static_cast<unsigned int>(1 << 10))
679 
680 #define TRACE_EVENT_FLAG_SCOPE_MASK                          \
681   (static_cast<unsigned int>(TRACE_EVENT_FLAG_SCOPE_OFFSET | \
682                              TRACE_EVENT_FLAG_SCOPE_EXTRA))
683 
684 // Type values for identifying types in the TraceValue union.
685 #define TRACE_VALUE_TYPE_BOOL (static_cast<unsigned char>(1))
686 #define TRACE_VALUE_TYPE_UINT (static_cast<unsigned char>(2))
687 #define TRACE_VALUE_TYPE_INT (static_cast<unsigned char>(3))
688 #define TRACE_VALUE_TYPE_DOUBLE (static_cast<unsigned char>(4))
689 #define TRACE_VALUE_TYPE_POINTER (static_cast<unsigned char>(5))
690 #define TRACE_VALUE_TYPE_STRING (static_cast<unsigned char>(6))
691 #define TRACE_VALUE_TYPE_COPY_STRING (static_cast<unsigned char>(7))
692 #define TRACE_VALUE_TYPE_CONVERTABLE (static_cast<unsigned char>(8))
693 
694 // Enum reflecting the scope of an INSTANT event. Must fit within TRACE_EVENT_FLAG_SCOPE_MASK.
695 #define TRACE_EVENT_SCOPE_GLOBAL (static_cast<unsigned char>(0 << 3))
696 #define TRACE_EVENT_SCOPE_PROCESS (static_cast<unsigned char>(1 << 3))
697 #define TRACE_EVENT_SCOPE_THREAD (static_cast<unsigned char>(2 << 3))
698 
699 #define TRACE_EVENT_SCOPE_NAME_GLOBAL ('g')
700 #define TRACE_EVENT_SCOPE_NAME_PROCESS ('p')
701 #define TRACE_EVENT_SCOPE_NAME_THREAD ('t')
702 
703 #endif  // SkTraceEventCommon_DEFINED
704