1 /*
2 * Copyright 2022 Google LLC
3 * SPDX-License-Identifier: MIT
4 */
5
6 #ifndef CPU_TRACE_H
7 #define CPU_TRACE_H
8
9 #include "u_perfetto.h"
10 #include "u_gpuvis.h"
11
12 #include "util/macros.h"
13
14 #if defined(HAVE_PERFETTO)
15
16 /* note that util_perfetto_is_category_enabled always returns false util
17 * util_perfetto_init is called
18 */
19 #define _MESA_TRACE_BEGIN(category, name) \
20 do { \
21 if (unlikely(util_perfetto_is_category_enabled(category))) \
22 util_perfetto_trace_begin(category, name); \
23 } while (0)
24
25 #define _MESA_TRACE_END(category) \
26 do { \
27 if (unlikely(util_perfetto_is_category_enabled(category))) \
28 util_perfetto_trace_end(category); \
29 } while (0)
30
31 /* NOTE: for now disable atrace for C++ to workaround a ndk bug with ordering
32 * between stdatomic.h and atomic.h. See:
33 *
34 * https://github.com/android/ndk/issues/1178
35 */
36 #elif defined(ANDROID) && !defined(__cplusplus)
37
38 #include <cutils/trace.h>
39
40 #define _MESA_TRACE_BEGIN(category, name) \
41 atrace_begin(ATRACE_TAG_GRAPHICS, name)
42 #define _MESA_TRACE_END(category) atrace_end(ATRACE_TAG_GRAPHICS)
43
44 #else
45
46 #define _MESA_TRACE_BEGIN(category, name)
47 #define _MESA_TRACE_END(category)
48
49 #endif /* HAVE_PERFETTO */
50
51 #if defined(HAVE_GPUVIS)
52
53 #define _MESA_GPUVIS_TRACE_BEGIN(name) util_gpuvis_begin(name)
54 #define _MESA_GPUVIS_TRACE_END() util_gpuvis_end()
55
56 #else
57
58 #define _MESA_GPUVIS_TRACE_BEGIN(name)
59 #define _MESA_GPUVIS_TRACE_END()
60
61 #endif /* HAVE_GPUVIS */
62
63
64 #define _MESA_COMBINED_TRACE_BEGIN(category, name) \
65 do { \
66 _MESA_TRACE_BEGIN(category, name); \
67 _MESA_GPUVIS_TRACE_BEGIN(name); \
68 } while (0)
69
70 #define _MESA_COMBINED_TRACE_END(category) \
71 do { \
72 _MESA_GPUVIS_TRACE_END(); \
73 _MESA_TRACE_END(category); \
74 } while (0)
75
76 #if __has_attribute(cleanup) && __has_attribute(unused)
77
78 #define _MESA_TRACE_SCOPE_VAR_CONCAT(name, suffix) name##suffix
79 #define _MESA_TRACE_SCOPE_VAR(suffix) \
80 _MESA_TRACE_SCOPE_VAR_CONCAT(_mesa_trace_scope_, suffix)
81
82 /* This must expand to a single non-scoped statement for
83 *
84 * if (cond)
85 * _MESA_TRACE_SCOPE(...)
86 *
87 * to work.
88 */
89 #define _MESA_TRACE_SCOPE(category, name) \
90 int _MESA_TRACE_SCOPE_VAR(__LINE__) \
91 __attribute__((cleanup(_mesa_trace_scope_end), unused)) = \
92 _mesa_trace_scope_begin(category, name)
93
94 static inline int
_mesa_trace_scope_begin(enum util_perfetto_category category,const char * name)95 _mesa_trace_scope_begin(enum util_perfetto_category category,
96 const char *name)
97 {
98 _MESA_COMBINED_TRACE_BEGIN(category, name);
99 return category;
100 }
101
102 static inline void
_mesa_trace_scope_end(int * scope)103 _mesa_trace_scope_end(int *scope)
104 {
105 /* we save the category in the scope variable */
106 _MESA_COMBINED_TRACE_END((enum util_perfetto_category) * scope);
107 }
108
109 #else
110
111 #define _MESA_TRACE_SCOPE(category, name)
112
113 #endif /* __has_attribute(cleanup) && __has_attribute(unused) */
114
115 /* These use the default category. Drivers or subsystems can use these, or
116 * define their own categories/macros.
117 */
118 #define MESA_TRACE_BEGIN(name) \
119 _MESA_COMBINED_TRACE_BEGIN(UTIL_PERFETTO_CATEGORY_DEFAULT, name)
120 #define MESA_TRACE_END() \
121 _MESA_COMBINED_TRACE_END(UTIL_PERFETTO_CATEGORY_DEFAULT)
122 #define MESA_TRACE_SCOPE(name) \
123 _MESA_TRACE_SCOPE(UTIL_PERFETTO_CATEGORY_DEFAULT, name)
124 #define MESA_TRACE_FUNC() \
125 _MESA_TRACE_SCOPE(UTIL_PERFETTO_CATEGORY_DEFAULT, __func__)
126
127 /* these use the slow category */
128 #define MESA_TRACE_BEGIN_SLOW(name) \
129 _MESA_COMBINED_TRACE_BEGIN(UTIL_PERFETTO_CATEGORY_SLOW, name)
130 #define MESA_TRACE_END_SLOW() \
131 _MESA_COMBINED_TRACE_END(UTIL_PERFETTO_CATEGORY_SLOW)
132 #define MESA_TRACE_SCOPE_SLOW(name) \
133 _MESA_TRACE_SCOPE(UTIL_PERFETTO_CATEGORY_SLOW, name)
134 #define MESA_TRACE_FUNC_SLOW() \
135 _MESA_TRACE_SCOPE(UTIL_PERFETTO_CATEGORY_SLOW, __func__)
136
137 static inline void
util_cpu_trace_init()138 util_cpu_trace_init()
139 {
140 util_perfetto_init();
141 util_gpuvis_init();
142 }
143
144 #endif /* CPU_TRACE_H */
145