2017-07-20 19:43:35 +00:00
|
|
|
/*
|
|
|
|
* 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"
|
2017-07-21 15:06:24 +00:00
|
|
|
#include "SkEventTracingPriv.h"
|
2017-07-24 15:38:01 +00:00
|
|
|
#include "SkSpinlock.h"
|
2017-07-20 19:43:35 +00:00
|
|
|
#include "SkString.h"
|
2017-08-01 14:23:38 +00:00
|
|
|
#include "SkTHash.h"
|
2017-07-20 19:43:35 +00:00
|
|
|
|
Added SkJSONWriter
This is a stand-alone helper class for writing properly
structured JSON to an SkWStream. It currently solves two
problems (although this CL only uses it in one context):
1) Performance. Writing out JSON this way is about 10x
faster than using JSONCPP. For the large amounts of data
generated by the tracing system, that's a big win.
2) Makes it easy to emit structured JSON from code that's
not fully centralized. We'd like to spit out JSON that
describes a GrContext, GrGpu, GrCaps, etc... Doing that
with simple string manipulation is complex, and spreads
this logic over all those functions. Using JSONCPP adds
yet another (large) third party library dependency (that
we only build into our own tools right now).
This went through several revisions. I originally planned
it as a stateful SkString wrapper, so the user could just
build their JSON as a string. That's O(N^2), though,
because SkString grows by a (small) constant amount. Even
using a better growth strategy still means needing RAM
for all the resulting text, which is usually pointless.
This version has a constant memory cost, so writing huge
amounts of JSON to disk (tracing a long DM run can emit
100's of MBs) doesn't stress resources.
Bug: skia:
Change-Id: Ia716524b246db0f97d332da60d2ce9903069e748
Reviewed-on: https://skia-review.googlesource.com/31204
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Klein <mtklein@chromium.org>
2017-08-09 13:25:39 +00:00
|
|
|
class SkJSONWriter;
|
|
|
|
|
2017-07-20 19:43:35 +00:00
|
|
|
/**
|
|
|
|
* A SkEventTracer implementation that logs events to JSON for viewing with chrome://tracing.
|
|
|
|
*/
|
|
|
|
class SkChromeTracingTracer : public SkEventTracer {
|
|
|
|
public:
|
2017-07-24 15:38:01 +00:00
|
|
|
SkChromeTracingTracer(const char* filename);
|
|
|
|
~SkChromeTracingTracer() override;
|
2017-07-20 19:43:35 +00:00
|
|
|
|
|
|
|
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;
|
|
|
|
|
2017-07-21 15:06:24 +00:00
|
|
|
const uint8_t* getCategoryGroupEnabled(const char* name) override {
|
|
|
|
return fCategories.getCategoryGroupEnabled(name);
|
|
|
|
}
|
2017-07-20 19:43:35 +00:00
|
|
|
|
|
|
|
const char* getCategoryGroupName(const uint8_t* categoryEnabledFlag) override {
|
2017-07-21 15:06:24 +00:00
|
|
|
return fCategories.getCategoryGroupName(categoryEnabledFlag);
|
2017-07-20 19:43:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
void flush();
|
|
|
|
|
2017-07-24 15:38:01 +00:00
|
|
|
enum {
|
2017-08-16 20:56:04 +00:00
|
|
|
// Events are variable size, but most commonly 48 bytes, assuming 64-bit pointers and
|
2017-08-16 14:31:29 +00:00
|
|
|
// reasonable packing. This is a first guess at a number that balances memory usage vs.
|
|
|
|
// time overhead of allocating blocks.
|
|
|
|
kBlockSize = 512 * 1024,
|
2017-07-24 15:38:01 +00:00
|
|
|
};
|
|
|
|
|
2017-08-16 14:31:29 +00:00
|
|
|
typedef std::unique_ptr<uint8_t[]> BlockPtr;
|
|
|
|
struct TraceEventBlock {
|
|
|
|
BlockPtr fBlock;
|
|
|
|
int fEventsInBlock;
|
2017-07-24 15:38:01 +00:00
|
|
|
};
|
|
|
|
|
2017-08-16 14:31:29 +00:00
|
|
|
void createBlock();
|
2017-08-01 14:23:38 +00:00
|
|
|
|
2017-08-16 14:31:29 +00:00
|
|
|
Handle appendEvent(const void* data, size_t size);
|
2017-07-24 15:38:01 +00:00
|
|
|
|
2017-07-20 19:43:35 +00:00
|
|
|
SkString fFilename;
|
2017-07-24 15:38:01 +00:00
|
|
|
SkSpinlock fMutex;
|
2017-07-21 15:06:24 +00:00
|
|
|
SkEventTracingCategories fCategories;
|
2017-08-16 14:31:29 +00:00
|
|
|
|
|
|
|
TraceEventBlock fCurBlock;
|
|
|
|
size_t fCurBlockUsed;
|
|
|
|
|
|
|
|
SkTArray<TraceEventBlock> fBlocks;
|
2017-07-20 19:43:35 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|