First stab at JSON event tracer
Not yet thread safe (so it forces threading off). Builds JSON on the fly, so overhead is certainly bad. Plan to fix all of that, but this at least "works". There is now one tracing flag: 'trace'. - 'debugf' installs the SkDebugf tracer. - 'atrace' installs the Android ATrace tracer. - Any other value is interpreted as a filename, and produces a JSON file for chrome://tracing. All three modes work in DM, nanobench, and Viewer. Bug: skia: Change-Id: I3fbc22382b99418a508c670be2770195c0a1c364 Reviewed-on: https://skia-review.googlesource.com/24781 Commit-Queue: Brian Osman <brianosman@google.com> Reviewed-by: Brian Salomon <bsalomon@google.com>
This commit is contained in:
parent
45c16fa82c
commit
53136aa93f
4
BUILD.gn
4
BUILD.gn
@ -1030,8 +1030,12 @@ if (skia_enable_tools) {
|
||||
"tools/sk_tool_utils.cpp",
|
||||
"tools/sk_tool_utils_font.cpp",
|
||||
"tools/timer/Timer.cpp",
|
||||
"tools/trace/SkChromeTracingTracer.cpp",
|
||||
"tools/trace/SkChromeTracingTracer.h",
|
||||
"tools/trace/SkDebugfTracer.cpp",
|
||||
"tools/trace/SkDebugfTracer.h",
|
||||
"tools/trace/SkEventTracingPriv.cpp",
|
||||
"tools/trace/SkEventTracingPriv.h",
|
||||
]
|
||||
libs = []
|
||||
if (is_ios) {
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "SkCommonFlagsPathRenderer.h"
|
||||
#include "SkData.h"
|
||||
#include "SkDebugfTracer.h"
|
||||
#include "SkEventTracingPriv.h"
|
||||
#include "SkGraphics.h"
|
||||
#include "SkLeanWindows.h"
|
||||
#include "SkOSFile.h"
|
||||
@ -1104,9 +1105,9 @@ static void start_keepalive() {
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
SkCommandLineFlags::Parse(argc, argv);
|
||||
if (FLAGS_trace) {
|
||||
SkEventTracer::SetInstance(new SkDebugfTracer);
|
||||
}
|
||||
|
||||
initializeEventTracingForTools(&FLAGS_threads);
|
||||
|
||||
#if defined(SK_BUILD_FOR_IOS)
|
||||
cd_Documents();
|
||||
#endif
|
||||
|
12
dm/DM.cpp
12
dm/DM.cpp
@ -11,6 +11,7 @@
|
||||
#include "Resources.h"
|
||||
#include "SkBBHFactory.h"
|
||||
#include "SkChecksum.h"
|
||||
#include "SkChromeTracingTracer.h"
|
||||
#include "SkCodec.h"
|
||||
#include "SkColorPriv.h"
|
||||
#include "SkColorSpace.h"
|
||||
@ -20,7 +21,7 @@
|
||||
#include "SkCommonFlagsPathRenderer.h"
|
||||
#include "SkData.h"
|
||||
#include "SkDebugfTracer.h"
|
||||
#include "SkEventTracer.h"
|
||||
#include "SkEventTracingPriv.h"
|
||||
#include "SkFontMgr.h"
|
||||
#include "SkGraphics.h"
|
||||
#include "SkHalf.h"
|
||||
@ -1272,10 +1273,10 @@ extern sk_sp<SkTypeface> (*gCreateTypefaceDelegate)(const char [], SkFontStyle )
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
SkCommandLineFlags::Parse(argc, argv);
|
||||
if (FLAGS_trace) {
|
||||
SkAssertResult(SkEventTracer::SetInstance(new SkDebugfTracer()));
|
||||
}
|
||||
#if defined(SK_BUILD_FOR_IOS)
|
||||
|
||||
initializeEventTracingForTools(&FLAGS_threads);
|
||||
|
||||
#if defined(SK_BUILD_FOR_IOS)
|
||||
cd_Documents();
|
||||
#endif
|
||||
setbuf(stdout, nullptr);
|
||||
@ -1386,6 +1387,7 @@ int main(int argc, char** argv) {
|
||||
|
||||
SkGraphics::PurgeAllCaches();
|
||||
info("Finished!\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -72,8 +72,6 @@ DEFINE_bool(forceAnalyticAA, false, "Force analytic anti-aliasing even if the pa
|
||||
"whether it's concave or convex, we consider a path complicated"
|
||||
"if its number of points is comparable to its resolution.");
|
||||
|
||||
DEFINE_bool(trace, false, "Show trace events using SkDebugf.");
|
||||
|
||||
bool CollectImages(SkCommandLineFlags::StringArray images, SkTArray<SkString>* output) {
|
||||
SkASSERT(output);
|
||||
|
||||
|
@ -34,7 +34,6 @@ DECLARE_string(writePath);
|
||||
DECLARE_bool(pre_log);
|
||||
DECLARE_bool(analyticAA);
|
||||
DECLARE_bool(forceAnalyticAA);
|
||||
DECLARE_bool(trace)
|
||||
|
||||
DECLARE_string(key);
|
||||
DECLARE_string(properties);
|
||||
|
96
tools/trace/SkChromeTracingTracer.cpp
Normal file
96
tools/trace/SkChromeTracingTracer.cpp
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright 2017 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "SkChromeTracingTracer.h"
|
||||
#include "SkThreadID.h"
|
||||
#include "SkTraceEvent.h"
|
||||
#include "SkOSFile.h"
|
||||
#include "SkOSPath.h"
|
||||
#include "SkStream.h"
|
||||
|
||||
#include <chrono>
|
||||
|
||||
SkEventTracer::Handle SkChromeTracingTracer::addTraceEvent(char phase,
|
||||
const uint8_t* categoryEnabledFlag,
|
||||
const char* name,
|
||||
uint64_t id,
|
||||
int numArgs,
|
||||
const char** argNames,
|
||||
const uint8_t* argTypes,
|
||||
const uint64_t* argValues,
|
||||
uint8_t flags) {
|
||||
Json::Value traceEvent;
|
||||
char phaseString[2] = { phase, 0 };
|
||||
traceEvent["ph"] = phaseString;
|
||||
traceEvent["name"] = name;
|
||||
traceEvent["cat"] = "skia"; // TODO
|
||||
auto now = std::chrono::high_resolution_clock::now();
|
||||
std::chrono::duration<double, std::nano> ns = now.time_since_epoch();
|
||||
traceEvent["ts"] = ns.count() * 1E-3;
|
||||
traceEvent["tid"] = static_cast<Json::Int64>(SkGetThreadID());
|
||||
traceEvent["pid"] = 1; // TODO
|
||||
|
||||
if (numArgs) {
|
||||
Json::Value args;
|
||||
for (int i = 0; i < numArgs; ++i) {
|
||||
switch (argTypes[i]) {
|
||||
case TRACE_VALUE_TYPE_BOOL:
|
||||
args[argNames[i]] = (*reinterpret_cast<bool*>(argValues[i]) ? true : false);
|
||||
break;
|
||||
case TRACE_VALUE_TYPE_UINT:
|
||||
args[argNames[i]] = static_cast<uint32_t>(argValues[i]);
|
||||
break;
|
||||
case TRACE_VALUE_TYPE_INT:
|
||||
args[argNames[i]] = static_cast<int32_t>(argValues[i]);
|
||||
break;
|
||||
case TRACE_VALUE_TYPE_DOUBLE:
|
||||
args[argNames[i]] = *SkTCast<const double*>(&argValues[i]);
|
||||
break;
|
||||
case TRACE_VALUE_TYPE_POINTER:
|
||||
args[argNames[i]] = reinterpret_cast<void*>(argValues[i]);
|
||||
break;
|
||||
case TRACE_VALUE_TYPE_STRING:
|
||||
case TRACE_VALUE_TYPE_COPY_STRING:
|
||||
args[argNames[i]] = reinterpret_cast<const char*>(argValues[i]);
|
||||
break;
|
||||
default:
|
||||
args[argNames[i]] = "<unknown type>";
|
||||
break;
|
||||
}
|
||||
}
|
||||
traceEvent["args"] = args;
|
||||
}
|
||||
Json::Value& newValue(fRoot.append(traceEvent));
|
||||
return reinterpret_cast<Handle>(&newValue);
|
||||
}
|
||||
|
||||
void SkChromeTracingTracer::updateTraceEventDuration(const uint8_t* categoryEnabledFlag,
|
||||
const char* name,
|
||||
SkEventTracer::Handle handle) {
|
||||
Json::Value* traceEvent = reinterpret_cast<Json::Value*>(handle);
|
||||
auto now = std::chrono::high_resolution_clock::now();
|
||||
std::chrono::duration<double, std::nano> ns = now.time_since_epoch();
|
||||
auto us = ns.count() * 1E-3;
|
||||
(*traceEvent)["dur"] = us - (*traceEvent)["ts"].asDouble();
|
||||
}
|
||||
|
||||
const uint8_t* SkChromeTracingTracer::getCategoryGroupEnabled(const char* name) {
|
||||
static uint8_t yes = SkEventTracer::kEnabledForRecording_CategoryGroupEnabledFlags;
|
||||
return &yes;
|
||||
}
|
||||
|
||||
void SkChromeTracingTracer::flush() {
|
||||
SkString dirname = SkOSPath::Dirname(fFilename.c_str());
|
||||
if (!sk_exists(dirname.c_str(), kWrite_SkFILE_Flag)) {
|
||||
if (!sk_mkdir(dirname.c_str())) {
|
||||
SkDebugf("Failed to create directory.");
|
||||
}
|
||||
}
|
||||
SkFILEWStream stream(fFilename.c_str());
|
||||
stream.writeText(Json::StyledWriter().write(fRoot).c_str());
|
||||
stream.flush();
|
||||
}
|
51
tools/trace/SkChromeTracingTracer.h
Normal file
51
tools/trace/SkChromeTracingTracer.h
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2017 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkChromeTracingTracer_DEFINED
|
||||
#define SkChromeTracingTracer_DEFINED
|
||||
|
||||
#include "SkEventTracer.h"
|
||||
#include "SkJSONCPP.h"
|
||||
#include "SkString.h"
|
||||
|
||||
/**
|
||||
* A SkEventTracer implementation that logs events to JSON for viewing with chrome://tracing.
|
||||
*/
|
||||
class SkChromeTracingTracer : public SkEventTracer {
|
||||
public:
|
||||
SkChromeTracingTracer(const char* filename) : fRoot(Json::arrayValue), fFilename(filename) {}
|
||||
~SkChromeTracingTracer() override { this->flush(); }
|
||||
|
||||
SkEventTracer::Handle addTraceEvent(char phase,
|
||||
const uint8_t* categoryEnabledFlag,
|
||||
const char* name,
|
||||
uint64_t id,
|
||||
int numArgs,
|
||||
const char** argNames,
|
||||
const uint8_t* argTypes,
|
||||
const uint64_t* argValues,
|
||||
uint8_t flags) override;
|
||||
|
||||
void updateTraceEventDuration(const uint8_t* categoryEnabledFlag,
|
||||
const char* name,
|
||||
SkEventTracer::Handle handle) override;
|
||||
|
||||
const uint8_t* getCategoryGroupEnabled(const char* name) override;
|
||||
|
||||
const char* getCategoryGroupName(const uint8_t* categoryEnabledFlag) override {
|
||||
static const char* category = "category?";
|
||||
return category;
|
||||
}
|
||||
|
||||
private:
|
||||
void flush();
|
||||
|
||||
Json::Value fRoot;
|
||||
SkString fFilename;
|
||||
};
|
||||
|
||||
#endif
|
44
tools/trace/SkEventTracingPriv.cpp
Normal file
44
tools/trace/SkEventTracingPriv.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2017 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "SkEventTracingPriv.h"
|
||||
|
||||
#include "SkATrace.h"
|
||||
#include "SkCommandLineFlags.h"
|
||||
#include "SkEventTracer.h"
|
||||
#include "SkChromeTracingTracer.h"
|
||||
#include "SkDebugfTracer.h"
|
||||
|
||||
DEFINE_string(trace, "",
|
||||
"Log trace events in one of several modes:\n"
|
||||
" debugf : Show events using SkDebugf\n"
|
||||
" atrace : Send events to Android ATrace\n"
|
||||
" <filename> : Any other string is interpreted as a filename. Writes\n"
|
||||
" trace events to specified file as JSON, for viewing\n"
|
||||
" with chrome://tracing");
|
||||
|
||||
void initializeEventTracingForTools(int32_t* threadsFlag) {
|
||||
if (FLAGS_trace.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const char* traceFlag = FLAGS_trace[0];
|
||||
SkEventTracer* eventTracer = nullptr;
|
||||
if (0 == strcmp(traceFlag, "atrace")) {
|
||||
eventTracer = new SkATrace();
|
||||
} else if (0 == strcmp(traceFlag, "debugf")) {
|
||||
eventTracer = new SkDebugfTracer();
|
||||
} else {
|
||||
if (threadsFlag && *threadsFlag != 0) {
|
||||
SkDebugf("JSON tracing is not yet thread-safe, disabling threading.\n");
|
||||
*threadsFlag = 0;
|
||||
}
|
||||
eventTracer = new SkChromeTracingTracer(traceFlag);
|
||||
}
|
||||
|
||||
SkAssertResult(SkEventTracer::SetInstance(eventTracer));
|
||||
}
|
22
tools/trace/SkEventTracingPriv.h
Normal file
22
tools/trace/SkEventTracingPriv.h
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright 2017 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkEventTracingPriv_DEFINED
|
||||
#define SkEventTracingPriv_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
|
||||
/**
|
||||
* Construct and install an SkEventTracer, based on the 'trace' command line argument.
|
||||
*
|
||||
* @param threadsFlag Pointer to the FLAGS_threads variable (or nullptr). This is used to disable
|
||||
* threading when tracing to JSON. (Remove this param when JSON tracer is thread
|
||||
* safe).
|
||||
*/
|
||||
void initializeEventTracingForTools(int32_t* threadsFlag);
|
||||
|
||||
#endif
|
@ -21,6 +21,7 @@
|
||||
#include "SkCommandLineFlags.h"
|
||||
#include "SkCommonFlagsPathRenderer.h"
|
||||
#include "SkDashPathEffect.h"
|
||||
#include "SkEventTracingPriv.h"
|
||||
#include "SkGraphics.h"
|
||||
#include "SkImagePriv.h"
|
||||
#include "SkMetaData.h"
|
||||
@ -157,12 +158,11 @@ static DEFINE_string(jpgs, "jpgs", "Directory to read jpgs from.");
|
||||
|
||||
static DEFINE_string2(backend, b, "sw", "Backend to use. Allowed values are " BACKENDS_STR ".");
|
||||
|
||||
static DEFINE_bool(atrace, false, "Enable support for using ATrace. ATrace is only supported on Android.");
|
||||
|
||||
DEFINE_int32(msaa, 0, "Number of subpixel samples. 0 for no HW antialiasing.");
|
||||
DEFINE_pathrenderer_flag;
|
||||
|
||||
DEFINE_bool(instancedRendering, false, "Enable instanced rendering on GPU backends.");
|
||||
DECLARE_int32(threads)
|
||||
|
||||
const char *kBackendTypeStrings[sk_app::Window::kBackendTypeCount] = {
|
||||
"OpenGL",
|
||||
@ -255,7 +255,6 @@ Viewer::Viewer(int argc, char** argv, void* platformData)
|
||||
, fZoomLevel(0.0f)
|
||||
, fGestureDevice(GestureDevice::kNone)
|
||||
{
|
||||
static SkTaskGroup::Enabler kTaskGroupEnabler;
|
||||
SkGraphics::Init();
|
||||
|
||||
static SkOnce initPathRendererNames;
|
||||
@ -285,9 +284,8 @@ Viewer::Viewer(int argc, char** argv, void* platformData)
|
||||
SetResourcePath("/data/local/tmp/resources");
|
||||
#endif
|
||||
|
||||
if (FLAGS_atrace) {
|
||||
SkAssertResult(SkEventTracer::SetInstance(new SkATrace()));
|
||||
}
|
||||
initializeEventTracingForTools(&FLAGS_threads);
|
||||
static SkTaskGroup::Enabler kTaskGroupEnabler(FLAGS_threads);
|
||||
|
||||
fBackendType = get_backend_type(FLAGS_backend[0]);
|
||||
fWindow = Window::CreateNativeWindow(platformData);
|
||||
|
Loading…
Reference in New Issue
Block a user