5#ifndef FLUTTER_FML_TRACE_EVENT_H_
6#define FLUTTER_FML_TRACE_EVENT_H_
10#include "flutter/fml/build_config.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)
62#include "flutter/fml/macros.h"
63#include "flutter/fml/time/time_point.h"
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());
239 int64_t timestamp_micros,
241 size_t flow_id_count,
242 const uint64_t* flow_ids,
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,
253 const std::vector<const char*>&
names,
254 const std::vector<std::string>&
values);
257 return std::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
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
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
374 const int64_t begin_micros =
begin.ToEpochDelta().ToMicroseconds();
375 const int64_t end_micros =
end.ToEpochDelta().ToMicroseconds();
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) {
void swap(sk_sp< T > &a, sk_sp< T > &b)
constexpr int64_t ToNanoseconds() const
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)
static SkString identifier(const FontFamilyDesc &family, const FontDesc &font)
static const char * begin(const StringSlice &s)
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
static const char *const names[]
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap The size limit in megabytes for the Dart VM old gen heap space enable Enable the Impeller renderer on supported platforms Ignored if Impeller is not supported on the platform enable vulkan Enable loading Vulkan validation layers The layers must be available to the application and loadable On non Vulkan this flag does nothing enable vulkan gpu tracing
DEF_SWITCHES_START aot vmservice shared library name
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace Enable an endless trace buffer The default is a ring buffer This is useful when very old events need to viewed For during application launch Memory usage will continue to grow indefinitely however Start app with an specific route defined on the framework flutter assets Path to the Flutter assets directory enable service port Allow the VM service to fallback to automatic port selection if binding to a specified port fails trace Trace early application lifecycle Automatically switches to an endless trace buffer trace skia allowlist
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)
static SkString to_string(int n)