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