• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "flutter/shell/common/skia_event_tracer_impl.h"
6 
7 #define TRACE_EVENT_HIDE_MACROS
8 #include <vector>
9 
10 #include "flutter/fml/logging.h"
11 #include "flutter/fml/trace_event.h"
12 #include "third_party/skia/include/utils/SkEventTracer.h"
13 #include "third_party/skia/include/utils/SkTraceEventPhase.h"
14 
15 namespace flutter {
16 
17 class FlutterEventTracer : public SkEventTracer {
18  public:
19   static constexpr const char* kSkiaTag = "skia";
20   static constexpr uint8_t kYes = 1;
21   static constexpr uint8_t kNo = 0;
22 
FlutterEventTracer(bool enabled)23   FlutterEventTracer(bool enabled) : enabled_(enabled ? kYes : kNo){};
24 
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)25   SkEventTracer::Handle addTraceEvent(char phase,
26                                       const uint8_t* category_enabled_flag,
27                                       const char* name,
28                                       uint64_t id,
29                                       int num_args,
30                                       const char** p_arg_names,
31                                       const uint8_t* p_arg_types,
32                                       const uint64_t* p_arg_values,
33                                       uint8_t flags) override {
34 #if defined(OS_FUCHSIA)
35     // In a manner analogous to "fml/trace_event.h", use Fuchsia's system
36     // tracing macros when running on Fuchsia.
37     switch (phase) {
38       case TRACE_EVENT_PHASE_BEGIN:
39       case TRACE_EVENT_PHASE_COMPLETE:
40         TRACE_DURATION_BEGIN(kSkiaTag, name);
41         break;
42       case TRACE_EVENT_PHASE_END:
43         TRACE_DURATION_END(kSkiaTag, name);
44         break;
45       case TRACE_EVENT_PHASE_INSTANT:
46         TRACE_INSTANT(kSkiaTag, name, TRACE_SCOPE_THREAD);
47         break;
48       case TRACE_EVENT_PHASE_ASYNC_BEGIN:
49         TRACE_ASYNC_BEGIN(kSkiaTag, name, id);
50         break;
51       case TRACE_EVENT_PHASE_ASYNC_END:
52         TRACE_ASYNC_END(kSkiaTag, name, id);
53         break;
54       default:
55         break;
56     }
57 #else   // defined(OS_FUCHSIA)
58     switch (phase) {
59       case TRACE_EVENT_PHASE_BEGIN:
60       case TRACE_EVENT_PHASE_COMPLETE:
61         fml::tracing::TraceEvent0(kSkiaTag, name);
62         break;
63       case TRACE_EVENT_PHASE_END:
64         fml::tracing::TraceEventEnd(name);
65         break;
66       case TRACE_EVENT_PHASE_INSTANT:
67         fml::tracing::TraceEventInstant0(kSkiaTag, name);
68         break;
69       case TRACE_EVENT_PHASE_ASYNC_BEGIN:
70         fml::tracing::TraceEventAsyncBegin0(kSkiaTag, name, id);
71         break;
72       case TRACE_EVENT_PHASE_ASYNC_END:
73         fml::tracing::TraceEventAsyncEnd0(kSkiaTag, name, id);
74         break;
75       default:
76         break;
77     }
78 #endif  // defined(OS_FUCHSIA)
79     return 0;
80   }
81 
updateTraceEventDuration(const uint8_t * category_enabled_flag,const char * name,SkEventTracer::Handle handle)82   void updateTraceEventDuration(const uint8_t* category_enabled_flag,
83                                 const char* name,
84                                 SkEventTracer::Handle handle) override {
85     // This is only ever called from a scoped trace event so we will just end
86     // the section.
87 #if defined(OS_FUCHSIA)
88     TRACE_DURATION_END(kSkiaTag, name);
89 #else
90     fml::tracing::TraceEventEnd(name);
91 #endif
92   }
93 
getCategoryGroupEnabled(const char * name)94   const uint8_t* getCategoryGroupEnabled(const char* name) override {
95     return &enabled_;
96   }
97 
getCategoryGroupName(const uint8_t * category_enabled_flag)98   const char* getCategoryGroupName(
99       const uint8_t* category_enabled_flag) override {
100     return kSkiaTag;
101   }
102 
enable()103   void enable() { enabled_ = kYes; }
104 
105  private:
106   uint8_t enabled_;
107   FML_DISALLOW_COPY_AND_ASSIGN(FlutterEventTracer);
108 };
109 
enableSkiaTracingCallback(const char * method,const char ** param_keys,const char ** param_values,intptr_t num_params,void * user_data,const char ** json_object)110 bool enableSkiaTracingCallback(const char* method,
111                                const char** param_keys,
112                                const char** param_values,
113                                intptr_t num_params,
114                                void* user_data,
115                                const char** json_object) {
116   FlutterEventTracer* tracer = static_cast<FlutterEventTracer*>(user_data);
117   tracer->enable();
118   *json_object = strdup("{\"type\":\"Success\"}");
119   return true;
120 }
121 
InitSkiaEventTracer(bool enabled)122 void InitSkiaEventTracer(bool enabled) {
123   // TODO(chinmaygarde): Leaked https://github.com/flutter/flutter/issues/30808.
124   auto tracer = new FlutterEventTracer(enabled);
125   Dart_RegisterRootServiceRequestCallback("_flutter.enableSkiaTracing",
126                                           enableSkiaTracingCallback,
127                                           static_cast<void*>(tracer));
128   // Initialize the binding to Skia's tracing events. Skia will
129   // take ownership of and clean up the memory allocated here.
130   SkEventTracer::SetInstance(tracer);
131 }
132 
133 }  // namespace flutter
134