5#include "flutter/shell/common/skia_event_tracer_impl.h"
7#define TRACE_EVENT_HIDE_MACROS
12#include "flutter/fml/logging.h"
13#include "flutter/fml/posix_wrappers.h"
14#include "flutter/fml/trace_event.h"
15#include "third_party/dart/runtime/include/dart_tools_api.h"
19#if defined(OS_FUCHSIA)
24#include <lib/trace-engine/context.h>
25#include <lib/trace-engine/instrumentation.h>
32#define TRACE_VALUE_TYPE_BOOL (static_cast<unsigned char>(1))
33#define TRACE_VALUE_TYPE_UINT (static_cast<unsigned char>(2))
34#define TRACE_VALUE_TYPE_INT (static_cast<unsigned char>(3))
35#define TRACE_VALUE_TYPE_DOUBLE (static_cast<unsigned char>(4))
36#define TRACE_VALUE_TYPE_POINTER (static_cast<unsigned char>(5))
37#define TRACE_VALUE_TYPE_STRING (static_cast<unsigned char>(6))
38#define TRACE_VALUE_TYPE_COPY_STRING (static_cast<unsigned char>(7))
39#define TRACE_VALUE_TYPE_CONVERTABLE (static_cast<unsigned char>(8))
49constexpr std::string_view kTraceCategoryPrefix =
"disabled-by-default-";
52constexpr std::string_view kShaderCategoryName =
53 "disabled-by-default-skia.shaders";
55#if !defined(OS_FUCHSIA)
57constexpr char kDevtoolsTagArg[] =
"devtoolsTag";
60constexpr char kShadersDevtoolsTag[] =
"shaders";
63#if defined(OS_FUCHSIA)
64template <
class T,
class U>
66 static_assert(
sizeof(
T) ==
sizeof(
U));
69 memcpy(&t, &u,
sizeof(t));
78 static constexpr const char*
kSkiaTag =
"skia";
79 static constexpr uint8_t
kYes = 1;
80 static constexpr uint8_t
kNo = 0;
83 const std::optional<std::vector<std::string>>&
allowlist)
84 : enabled_(enabled ?
kYes :
kNo) {
87 for (
const std::string& category : *
allowlist) {
88 allowlist_->insert(std::string(kTraceCategoryPrefix) + category);
94 const uint8_t* category_enabled_flag,
98 const char** p_arg_names,
99 const uint8_t* p_arg_types,
100 const uint64_t* p_arg_values,
101 uint8_t
flags)
override {
102#if defined(OS_FUCHSIA)
103 static trace_site_t trace_site;
104 trace_string_ref_t category_ref;
105 trace_context_t* trace_context = trace_acquire_context_for_category_cached(
106 kSkiaTag, &trace_site, &category_ref);
108 if (likely(!trace_context)) {
112 trace_ticks_t ticks = zx_ticks_get();
114 trace_thread_ref_t thread_ref;
115 trace_context_register_current_thread(trace_context, &thread_ref);
116 trace_string_ref_t name_ref;
117 trace_context_register_string_literal(trace_context,
name, &name_ref);
119 constexpr int kMaxArgs = 2;
120 trace_arg_t trace_args[kMaxArgs] = {};
122 int num_trace_args =
std::min(kMaxArgs, num_args);
124 for (
int i = 0;
i < num_trace_args;
i++) {
125 const char* arg_name = p_arg_names[
i];
126 const uint8_t arg_type = p_arg_types[
i];
127 const uint64_t arg_value = p_arg_values[
i];
129 trace_string_ref_t arg_name_string_ref =
130 trace_context_make_registered_string_literal(trace_context, arg_name);
132 trace_arg_value_t trace_arg_value;
135 trace_arg_value = trace_make_bool_arg_value(!!arg_value);
139 trace_arg_value = trace_make_uint64_arg_value(arg_value);
143 trace_make_int64_arg_value(BitCast<int64_t>(arg_value));
147 trace_make_double_arg_value(BitCast<double>(arg_value));
151 trace_make_pointer_arg_value(BitCast<uintptr_t>(arg_value));
154 trace_string_ref_t arg_value_string_ref =
155 trace_context_make_registered_string_literal(
156 trace_context,
reinterpret_cast<const char*
>(arg_value));
157 trace_arg_value = trace_make_string_arg_value(arg_value_string_ref);
161 const char* arg_value_as_cstring =
162 reinterpret_cast<const char*
>(arg_value);
163 trace_string_ref_t arg_value_string_ref =
164 trace_context_make_registered_string_copy(
165 trace_context, arg_value_as_cstring,
166 strlen(arg_value_as_cstring));
167 trace_arg_value = trace_make_string_arg_value(arg_value_string_ref);
171 trace_arg_value = trace_make_null_arg_value();
174 trace_arg_value = trace_make_null_arg_value();
177 trace_args[
i] = trace_make_arg(arg_name_string_ref, trace_arg_value);
183 trace_context_write_duration_begin_event_record(
184 trace_context, ticks, &thread_ref, &category_ref, &name_ref,
185 trace_args, num_trace_args);
188 trace_context_write_duration_end_event_record(
189 trace_context, ticks, &thread_ref, &category_ref, &name_ref,
190 trace_args, num_trace_args);
193 trace_context_write_instant_event_record(
194 trace_context, ticks, &thread_ref, &category_ref, &name_ref,
195 TRACE_SCOPE_THREAD, trace_args, num_trace_args);
198 trace_context_write_async_begin_event_record(
199 trace_context, ticks, &thread_ref, &category_ref, &name_ref,
id,
200 trace_args, num_trace_args);
203 trace_context_write_async_end_event_record(
204 trace_context, ticks, &thread_ref, &category_ref, &name_ref,
id,
205 trace_args, num_trace_args);
211 trace_release_context(trace_context);
214 const char* devtoolsTag =
nullptr;
215 if (shaders_category_flag_ &&
216 category_enabled_flag == shaders_category_flag_) {
217 devtoolsTag = kShadersDevtoolsTag;
224 nullptr, kDevtoolsTagArg,
239 kDevtoolsTagArg, devtoolsTag);
251 kDevtoolsTagArg, devtoolsTag);
278#if defined(OS_FUCHSIA)
287 std::lock_guard<std::mutex> lock(flag_map_mutex_);
288 auto flag_it = category_flag_map_.find(
name);
289 if (flag_it == category_flag_map_.end()) {
292 allowed = !allowlist_.has_value() ||
293 allowlist_->find(
name) != allowlist_->end();
297 flag_it = category_flag_map_.insert(std::make_pair(
name, allowed)).first;
298 const uint8_t*
flag = &flag_it->second;
299 reverse_flag_map_.insert(std::make_pair(
flag,
name));
300 if (kShaderCategoryName ==
name) {
301 shaders_category_flag_ =
flag;
304 return &flag_it->second;
308 const uint8_t* category_enabled_flag)
override {
309 std::lock_guard<std::mutex> lock(flag_map_mutex_);
310 auto reverse_it = reverse_flag_map_.find(category_enabled_flag);
311 if (reverse_it != reverse_flag_map_.end()) {
312 return reverse_it->second;
320 std::optional<std::set<std::string>> allowlist_;
321 std::mutex flag_map_mutex_;
322 std::map<const char*, uint8_t> category_flag_map_;
323 std::map<const uint8_t*, const char*> reverse_flag_map_;
324 const uint8_t* shaders_category_flag_ =
nullptr;
330 const std::optional<std::vector<std::string>>&
allowlist) {
#define TRACE_VALUE_TYPE_STRING
#define TRACE_VALUE_TYPE_BOOL
#define TRACE_VALUE_TYPE_POINTER
#define TRACE_VALUE_TYPE_COPY_STRING
#define TRACE_VALUE_TYPE_INT
#define TRACE_VALUE_TYPE_UINT
#define TRACE_VALUE_TYPE_DOUBLE
#define TRACE_VALUE_TYPE_CONVERTABLE
#define TRACE_EVENT_PHASE_ASYNC_BEGIN
#define TRACE_EVENT_PHASE_END
#define TRACE_EVENT_PHASE_BEGIN
#define TRACE_EVENT_PHASE_INSTANT
#define TRACE_EVENT_PHASE_COMPLETE
#define TRACE_EVENT_PHASE_ASYNC_END
static bool SetInstance(SkEventTracer *, bool leakTracer=false)
void updateTraceEventDuration(const uint8_t *category_enabled_flag, const char *name, SkEventTracer::Handle handle) override
FlutterEventTracer(bool enabled, const std::optional< std::vector< std::string > > &allowlist)
static constexpr const char * kSkiaTag
const uint8_t * getCategoryGroupEnabled(const char *name) override
static constexpr uint8_t kNo
SkEventTracer::Handle addTraceEvent(char phase, const uint8_t *category_enabled_flag, const char *name, uint64_t id, int num_args, const char **p_arg_names, const uint8_t *p_arg_types, const uint64_t *p_arg_values, uint8_t flags) override
static constexpr uint8_t kYes
const char * getCategoryGroupName(const uint8_t *category_enabled_flag) override
FlutterSemanticsFlag flag
FlutterSemanticsFlag flags
#define FML_DCHECK(condition)
static float min(float r, float g, float b)
Dest BitCast(const Source &source)
void InitSkiaEventTracer(bool enabled, const std::optional< std::vector< std::string > > &allowlist)
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 TraceEventInstant0(TraceArg category_group, TraceArg name, size_t flow_id_count, const uint64_t *flow_ids)
void TraceEventAsyncBegin0(TraceArg category_group, TraceArg name, TraceIDArg id, size_t flow_id_count, const uint64_t *flow_ids)
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)
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 TraceEventAsyncEnd1(TraceArg category_group, TraceArg name, TraceIDArg id, TraceArg arg1_name, TraceArg arg1_val)
void TraceEventEnd(TraceArg name)
void TraceEvent1(TraceArg category_group, TraceArg name, size_t flow_id_count, const uint64_t *flow_ids, TraceArg arg1_name, TraceArg arg1_val)