5#ifndef FLUTTER_FML_TRACE_EVENT_H_
6#define FLUTTER_FML_TRACE_EVENT_H_
12#if defined(OS_FUCHSIA)
16#include <lib/trace/event.h>
20#define FML_TRACE_COUNTER(a, b, c, arg1, ...) \
21 ::fml::tracing::TraceCounterNopHACK((a), (b), (c), (arg1), __VA_ARGS__);
23#define FML_TRACE_EVENT(a, b, args...) TRACE_DURATION(a, b)
25#define FML_TRACE_EVENT_WITH_FLOW_IDS(category_group, name, flow_id_count, \
27 FML_TRACE_EVENT(category_group, name)
29#define TRACE_EVENT0(a, b) TRACE_DURATION(a, b)
31#define TRACE_EVENT0_WITH_FLOW_IDS(category_group, name, flow_id_count, \
33 TRACE_EVENT0(category_group, name)
34#define TRACE_EVENT1(a, b, c, d) TRACE_DURATION(a, b, c, d)
36#define TRACE_EVENT1_WITH_FLOW_IDS(category_group, name, flow_id_count, \
37 flow_ids, arg1_name, arg1_val) \
38 TRACE_EVENT1(category_group, name, arg1_name, arg1_val)
39#define TRACE_EVENT2(a, b, c, d, e, f) TRACE_DURATION(a, b, c, d, e, f)
40#define TRACE_EVENT_ASYNC_BEGIN0(a, b, c) TRACE_ASYNC_BEGIN(a, b, c)
42#define TRACE_EVENT_ASYNC_BEGIN0_WITH_FLOW_IDS(category_group, name, id, \
43 flow_id_count, flow_ids) \
44 TRACE_EVENT_ASYNC_BEGIN0(category_group, name, id)
45#define TRACE_EVENT_ASYNC_END0(a, b, c) TRACE_ASYNC_END(a, b, c)
46#define TRACE_EVENT_ASYNC_BEGIN1(a, b, c, d, e) TRACE_ASYNC_BEGIN(a, b, c, d, e)
47#define TRACE_EVENT_ASYNC_END1(a, b, c, d, e) TRACE_ASYNC_END(a, b, c, d, e)
48#define TRACE_EVENT_INSTANT0(a, b) TRACE_INSTANT(a, b, TRACE_SCOPE_THREAD)
49#define TRACE_EVENT_INSTANT1(a, b, k1, v1) \
50 TRACE_INSTANT(a, b, TRACE_SCOPE_THREAD, k1, v1)
51#define TRACE_EVENT_INSTANT2(a, b, k1, v1, k2, v2) \
52 TRACE_INSTANT(a, b, TRACE_SCOPE_THREAD, k1, v1, k2, v2)
64#include "third_party/dart/runtime/include/dart_tools_api.h"
66#if (FLUTTER_RELEASE && !defined(OS_FUCHSIA) && !defined(FML_OS_ANDROID))
67#define FLUTTER_TIMELINE_ENABLED 0
69#define FLUTTER_TIMELINE_ENABLED 1
72#if !defined(OS_FUCHSIA)
73#ifndef TRACE_EVENT_HIDE_MACROS
75#define __FML__TOKEN_CAT__(x, y) x##y
76#define __FML__TOKEN_CAT__2(x, y) __FML__TOKEN_CAT__(x, y)
77#define __FML__AUTO_TRACE_END(name) \
78 ::fml::tracing::ScopedInstantEnd __FML__TOKEN_CAT__2(__trace_end_, \
85#define FML_TRACE_COUNTER(category_group, name, counter_id, arg1, ...) \
86 ::fml::tracing::TraceCounter((category_group), (name), (counter_id), (arg1), \
102#define FML_TRACE_EVENT_WITH_FLOW_IDS(category_group, name, flow_id_count, \
104 ::fml::tracing::TraceEvent((category_group), (name), (flow_id_count), \
105 (flow_ids), __VA_ARGS__); \
106 __FML__AUTO_TRACE_END(name)
121#define FML_TRACE_EVENT(category_group, name, ...) \
122 FML_TRACE_EVENT_WITH_FLOW_IDS((category_group), (name), \
126#define TRACE_EVENT0_WITH_FLOW_IDS(category_group, name, flow_id_count, \
128 ::fml::tracing::TraceEvent0(category_group, name, flow_id_count, flow_ids); \
129 __FML__AUTO_TRACE_END(name)
131#define TRACE_EVENT0(category_group, name) \
132 TRACE_EVENT0_WITH_FLOW_IDS(category_group, name, 0, \
135#define TRACE_EVENT1_WITH_FLOW_IDS(category_group, name, flow_id_count, \
136 flow_ids, arg1_name, arg1_val) \
137 ::fml::tracing::TraceEvent1(category_group, name, flow_id_count, flow_ids, \
138 arg1_name, arg1_val); \
139 __FML__AUTO_TRACE_END(name)
141#define TRACE_EVENT1(category_group, name, arg1_name, arg1_val) \
142 TRACE_EVENT1_WITH_FLOW_IDS(category_group, name, 0, \
143 nullptr, arg1_name, arg1_val)
145#define TRACE_EVENT2(category_group, name, arg1_name, arg1_val, arg2_name, \
147 ::fml::tracing::TraceEvent2(category_group, name, 0, \
148 nullptr, arg1_name, arg1_val, \
149 arg2_name, arg2_val); \
150 __FML__AUTO_TRACE_END(name)
152#define TRACE_EVENT_ASYNC_BEGIN0_WITH_FLOW_IDS(category_group, name, id, \
153 flow_id_count, flow_ids) \
154 ::fml::tracing::TraceEventAsyncBegin0(category_group, name, id, \
155 flow_id_count, flow_ids);
157#define TRACE_EVENT_ASYNC_BEGIN0(category_group, name, id) \
158 TRACE_EVENT_ASYNC_BEGIN0_WITH_FLOW_IDS( \
159 category_group, name, id, 0, nullptr)
161#define TRACE_EVENT_ASYNC_END0(category_group, name, id) \
162 ::fml::tracing::TraceEventAsyncEnd0(category_group, name, id);
164#define TRACE_EVENT_ASYNC_BEGIN1(category_group, name, id, arg1_name, \
166 ::fml::tracing::TraceEventAsyncBegin1( \
167 category_group, name, id, 0, nullptr, \
168 arg1_name, arg1_val);
170#define TRACE_EVENT_ASYNC_END1(category_group, name, id, arg1_name, arg1_val) \
171 ::fml::tracing::TraceEventAsyncEnd1( \
172 category_group, name, id, 0, nullptr, \
173 arg1_name, arg1_val);
175#define TRACE_EVENT_INSTANT0(category_group, name) \
176 ::fml::tracing::TraceEventInstant0( \
177 category_group, name, 0, nullptr);
179#define TRACE_EVENT_INSTANT1(category_group, name, arg1_name, arg1_val) \
180 ::fml::tracing::TraceEventInstant1( \
181 category_group, name, 0, nullptr, \
182 arg1_name, arg1_val);
184#define TRACE_EVENT_INSTANT2(category_group, name, arg1_name, arg1_val, \
185 arg2_name, arg2_val) \
186 ::fml::tracing::TraceEventInstant2( \
187 category_group, name, 0, nullptr, \
188 arg1_name, arg1_val, arg2_name, arg2_val);
190#define TRACE_FLOW_BEGIN(category, name, id) \
191 ::fml::tracing::TraceEventFlowBegin0(category, name, id);
193#define TRACE_FLOW_STEP(category, name, id) \
194 ::fml::tracing::TraceEventFlowStep0(category, name, id);
196#define TRACE_FLOW_END(category, name, id) \
197 ::fml::tracing::TraceEventFlowEnd0(category, name, id);
202#define TRACE_EVENT2_INT(category_group, name, arg1_name, arg1_val, arg2_name, \
204 const auto __arg1_val_str = std::to_string(arg1_val); \
205 const auto __arg2_val_str = std::to_string(arg2_val); \
206 TRACE_EVENT2(category_group, name, arg1_name, __arg1_val_str.c_str(), \
207 arg2_name, __arg2_val_str.c_str());
222 Dart_Timeline_Event_Type,
239 int64_t timestamp_micros,
241 size_t flow_id_count,
242 const uint64_t* flow_ids,
243 Dart_Timeline_Event_Type
type,
244 const std::vector<const char*>& names,
245 const std::vector<std::string>& values);
250 size_t flow_id_count,
251 const uint64_t* flow_ids,
252 Dart_Timeline_Event_Type
type,
253 const std::vector<const char*>& names,
254 const std::vector<std::string>& values);
257 return std::string{
string};
268template <typename T, typename = std::enable_if_t<std::is_arithmetic<T>::value>>
270 return std::to_string(
string);
274 std::vector<std::string>& values) {}
276template <
typename Key,
typename Value,
typename... Args>
278 std::vector<std::string>& values,
282 keys.emplace_back(
key);
287inline std::pair<std::vector<const char*>, std::vector<std::string>>
292template <
typename Key,
typename Value,
typename... Args>
293std::pair<std::vector<const char*>, std::vector<std::string>>
295 std::vector<const char*> keys;
296 std::vector<std::string> values;
298 return std::make_pair(std::move(keys), std::move(values));
303template <
typename... Args>
308#if FLUTTER_TIMELINE_ENABLED
311 nullptr, Dart_Timeline_Event_Counter,
312 split.first, split.second);
318template <
typename... Args>
324template <
typename... Args>
327 size_t flow_id_count,
328 const uint64_t* flow_ids,
330#if FLUTTER_TIMELINE_ENABLED
333 Dart_Timeline_Event_Begin, split.first, split.second);
339 size_t flow_id_count,
340 const uint64_t* flow_ids);
344 size_t flow_id_count,
345 const uint64_t* flow_ids,
351 size_t flow_id_count,
352 const uint64_t* flow_ids,
360template <
typename... Args>
366#if FLUTTER_TIMELINE_ENABLED
371 std::swap(begin,
end);
375 const int64_t end_micros =
end.ToEpochDelta().ToMicroseconds();
383 Dart_Timeline_Event_Async_Begin,
394 Dart_Timeline_Event_Async_End,
404 size_t flow_id_count,
405 const uint64_t* flow_ids);
412 size_t flow_id_count,
413 const uint64_t* flow_ids,
425 size_t flow_id_count,
426 const uint64_t* flow_ids);
430 size_t flow_id_count,
431 const uint64_t* flow_ids,
437 size_t flow_id_count,
438 const uint64_t* flow_ids,
484 void Step(
const char* label =
nullptr)
const {
491 void End(
const char* label =
nullptr) {
constexpr int64_t ToMicroseconds() const
constexpr int64_t ToNanoseconds() const
constexpr TimeDelta ToEpochDelta() const
ScopedInstantEnd(const char *str)
void End(const char *label=nullptr)
void Step(const char *label=nullptr) const
TraceFlow(const char *label)
TraceFlow(TraceFlow &&other)
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
const gchar FlBinaryMessengerMessageHandler handler
#define FML_DISALLOW_COPY_AND_ASSIGN(TypeName)
void TraceEventFlowEnd0(TraceArg category_group, TraceArg name, TraceIDArg id)
void TraceEventInstant0(TraceArg category_group, TraceArg name, size_t flow_id_count, const uint64_t *flow_ids)
std::string TraceToString(const char *string)
void TraceEventFlowBegin0(TraceArg category_group, TraceArg name, TraceIDArg id)
bool TraceHasTimelineEventHandler()
void TraceEventAsyncBegin0(TraceArg category_group, TraceArg name, TraceIDArg id, size_t flow_id_count, const uint64_t *flow_ids)
void TraceSetAllowlist(const std::vector< std::string > &allowlist)
void TraceEventAsyncEnd0(TraceArg category_group, TraceArg name, TraceIDArg id)
void TraceEvent0(TraceArg category_group, TraceArg name, size_t flow_id_count, const uint64_t *flow_ids)
void TraceEventInstant1(TraceArg category_group, TraceArg name, size_t flow_id_count, const uint64_t *flow_ids, TraceArg arg1_name, TraceArg arg1_val)
int64_t(*)() TimelineMicrosSource
void TraceEventAsyncBegin1(TraceArg category_group, TraceArg name, TraceIDArg id, size_t flow_id_count, const uint64_t *flow_ids, TraceArg arg1_name, TraceArg arg1_val)
void TraceTimelineEvent(TraceArg category_group, TraceArg name, int64_t timestamp_micros, TraceIDArg identifier, size_t flow_id_count, const uint64_t *flow_ids, Dart_Timeline_Event_Type type, const std::vector< const char * > &c_names, const std::vector< std::string > &values)
void SplitArgumentsCollect(std::vector< const char * > &keys, std::vector< std::string > &values)
void TraceSetTimelineEventHandler(TimelineEventHandler handler)
void TraceSetTimelineMicrosSource(TimelineMicrosSource source)
void TraceEvent2(TraceArg category_group, TraceArg name, size_t flow_id_count, const uint64_t *flow_ids, TraceArg arg1_name, TraceArg arg1_val, TraceArg arg2_name, TraceArg arg2_val)
void TraceEventAsyncEnd1(TraceArg category_group, TraceArg name, TraceIDArg id, TraceArg arg1_name, TraceArg arg1_val)
void TraceEventEnd(TraceArg name)
void TraceEventInstant2(TraceArg category_group, TraceArg name, size_t flow_id_count, const uint64_t *flow_ids, TraceArg arg1_name, TraceArg arg1_val, TraceArg arg2_name, TraceArg arg2_val)
void TraceEvent(TraceArg category, TraceArg name, size_t flow_id_count, const uint64_t *flow_ids, Args... args)
int64_t TraceGetTimelineMicros()
void TraceCounter(TraceArg category, TraceArg name, TraceIDArg identifier, Args... args)
std::pair< std::vector< const char * >, std::vector< std::string > > SplitArguments()
void TraceEvent1(TraceArg category_group, TraceArg name, size_t flow_id_count, const uint64_t *flow_ids, TraceArg arg1_name, TraceArg arg1_val)
void(* TimelineEventHandler)(const char *, int64_t, int64_t, intptr_t, const int64_t *, Dart_Timeline_Event_Type, intptr_t, const char **, const char **)
void TraceCounterNopHACK(TraceArg category, TraceArg name, TraceIDArg identifier, Args... args)
void TraceEventAsyncComplete(TraceArg category_group, TraceArg name, TimePoint begin, TimePoint end)
void TraceEventFlowStep0(TraceArg category_group, TraceArg name, TraceIDArg id)