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