1 /*
2 * Copyright 2017 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "tools/trace/EventTracingPriv.h"
9
10 #include "include/utils/SkEventTracer.h"
11 #include "src/core/SkATrace.h"
12 #include "src/core/SkTraceEvent.h"
13 #include "tools/flags/CommandLineFlags.h"
14 #include "tools/trace/ChromeTracingTracer.h"
15 #include "tools/trace/SkDebugfTracer.h"
16
17 static DEFINE_string(trace,
18 "",
19 "Log trace events in one of several modes:\n"
20 " debugf : Show events using SkDebugf\n"
21 " atrace : Send events to Android ATrace\n"
22 " <filename> : Any other string is interpreted as a filename. Writes\n"
23 " trace events to specified file as JSON, for viewing\n"
24 " with chrome://tracing");
25
26 static DEFINE_string(traceMatch,
27 "",
28 "Filter which categories are traced.\n"
29 "Uses same format as --match\n");
30
initializeEventTracingForTools(const char * traceFlag)31 void initializeEventTracingForTools(const char* traceFlag) {
32 if (!traceFlag) {
33 if (FLAGS_trace.isEmpty()) {
34 return;
35 }
36 traceFlag = FLAGS_trace[0];
37 }
38
39 SkEventTracer* eventTracer = nullptr;
40 if (0 == strcmp(traceFlag, "atrace")) {
41 eventTracer = new SkATrace();
42 } else if (0 == strcmp(traceFlag, "debugf")) {
43 eventTracer = new SkDebugfTracer();
44 } else {
45 eventTracer = new ChromeTracingTracer(traceFlag);
46 }
47
48 SkAssertResult(SkEventTracer::SetInstance(eventTracer));
49 }
50
getCategoryGroupEnabled(const char * name)51 uint8_t* SkEventTracingCategories::getCategoryGroupEnabled(const char* name) {
52 static_assert(0 == offsetof(CategoryState, fEnabled), "CategoryState");
53
54 // We ignore the "disabled-by-default-" prefix in our internal tools
55 if (SkStrStartsWith(name, TRACE_CATEGORY_PREFIX)) {
56 name += strlen(TRACE_CATEGORY_PREFIX);
57 }
58
59 // Chrome's implementation of this API does a two-phase lookup (once without a lock, then again
60 // with a lock. But the tracing macros avoid calling these functions more than once per site,
61 // so just do something simple (and easier to reason about):
62 SkAutoMutexExclusive lock(fMutex);
63 for (int i = 0; i < fNumCategories; ++i) {
64 if (0 == strcmp(name, fCategories[i].fName)) {
65 return reinterpret_cast<uint8_t*>(&fCategories[i]);
66 }
67 }
68
69 if (fNumCategories >= kMaxCategories) {
70 SkDEBUGFAIL("Exhausted event tracing categories. Increase kMaxCategories.");
71 return reinterpret_cast<uint8_t*>(&fCategories[0]);
72 }
73
74 fCategories[fNumCategories].fEnabled =
75 CommandLineFlags::ShouldSkip(FLAGS_traceMatch, name)
76 ? 0
77 : SkEventTracer::kEnabledForRecording_CategoryGroupEnabledFlags;
78
79 fCategories[fNumCategories].fName = name;
80 return reinterpret_cast<uint8_t*>(&fCategories[fNumCategories++]);
81 }
82
getCategoryGroupName(const uint8_t * categoryEnabledFlag)83 const char* SkEventTracingCategories::getCategoryGroupName(const uint8_t* categoryEnabledFlag) {
84 if (categoryEnabledFlag) {
85 return reinterpret_cast<const CategoryState*>(categoryEnabledFlag)->fName;
86 }
87 return nullptr;
88 }
89