55#include " flutter/shell/common/skia_event_tracer_impl.h"
66
77#define TRACE_EVENT_HIDE_MACROS
8+ #include < map>
9+ #include < set>
810#include < vector>
911
1012#include " flutter/fml/logging.h"
@@ -42,6 +44,10 @@ namespace flutter {
4244
4345namespace {
4446
47+ // Skia prepends this string to the category names of its trace events.
48+ // Defined in Skia's src/core/SkTraceEvent.h.
49+ constexpr std::string_view kTraceCategoryPrefix = " disabled-by-default-" ;
50+
4551#if defined(OS_FUCHSIA)
4652template <class T , class U >
4753inline T BitCast (const U& u) {
@@ -61,7 +67,12 @@ class FlutterEventTracer : public SkEventTracer {
6167 static constexpr uint8_t kYes = 1 ;
6268 static constexpr uint8_t kNo = 0 ;
6369
64- FlutterEventTracer (bool enabled) : enabled_(enabled ? kYes : kNo ){};
70+ FlutterEventTracer (bool enabled, const std::vector<std::string>& allowlist)
71+ : enabled_(enabled ? kYes : kNo ) {
72+ for (const std::string& category : allowlist) {
73+ allowlist_.insert (std::string (kTraceCategoryPrefix ) + category);
74+ }
75+ };
6576
6677 SkEventTracer::Handle addTraceEvent (char phase,
6778 const uint8_t * category_enabled_flag,
@@ -221,39 +232,43 @@ class FlutterEventTracer : public SkEventTracer {
221232 }
222233
223234 const uint8_t * getCategoryGroupEnabled (const char * name) override {
224- return &enabled_;
235+ // Skia will only use long-lived string literals as event names.
236+ auto flag_it = category_flag_map_.find (name);
237+ if (flag_it == category_flag_map_.end ()) {
238+ bool allowed;
239+ if (enabled_) {
240+ allowed = allowlist_.empty () ||
241+ allowlist_.find (name) != allowlist_.end ();
242+ } else {
243+ allowed = false ;
244+ }
245+ flag_it = category_flag_map_.insert (std::make_pair (name, allowed)).first ;
246+ reverse_flag_map_.insert (std::make_pair (&flag_it->second , name));
247+ }
248+ return &flag_it->second ;
225249 }
226250
227251 const char * getCategoryGroupName (
228252 const uint8_t * category_enabled_flag) override {
229- return kSkiaTag ;
253+ auto reverse_it = reverse_flag_map_.find (category_enabled_flag);
254+ if (reverse_it != reverse_flag_map_.end ()) {
255+ return reverse_it->second ;
256+ } else {
257+ return kSkiaTag ;
258+ }
230259 }
231260
232- void enable () { enabled_ = kYes ; }
233-
234261 private:
235262 uint8_t enabled_;
263+ std::set<std::string> allowlist_;
264+ std::map<const char *, uint8_t > category_flag_map_;
265+ std::map<const uint8_t *, const char *> reverse_flag_map_;
236266 FML_DISALLOW_COPY_AND_ASSIGN (FlutterEventTracer);
237267};
238268
239- bool enableSkiaTracingCallback (const char * method,
240- const char ** param_keys,
241- const char ** param_values,
242- intptr_t num_params,
243- void * user_data,
244- const char ** json_object) {
245- FlutterEventTracer* tracer = static_cast <FlutterEventTracer*>(user_data);
246- tracer->enable ();
247- *json_object = fml::strdup (" {\" type\" :\" Success\" }" );
248- return true ;
249- }
250-
251- void InitSkiaEventTracer (bool enabled) {
252- // TODO(chinmaygarde): Leaked https://github.com/flutter/flutter/issues/30808.
253- auto tracer = new FlutterEventTracer (enabled);
254- Dart_RegisterRootServiceRequestCallback (" _flutter.enableSkiaTracing" ,
255- enableSkiaTracingCallback,
256- static_cast <void *>(tracer));
269+ void InitSkiaEventTracer (bool enabled,
270+ const std::vector<std::string>& allowlist) {
271+ auto tracer = new FlutterEventTracer (enabled, allowlist);
257272 // Initialize the binding to Skia's tracing events. Skia will
258273 // take ownership of and clean up the memory allocated here.
259274 SkEventTracer::SetInstance (tracer);
0 commit comments