47 return reinterpret_cast<TraceEvent*
>(
reinterpret_cast<char*
>(
this) + fSize);
49 TraceEventArg*
args() {
return reinterpret_cast<TraceEventArg*
>(
this + 1); }
50 char* stringTable() {
return reinterpret_cast<char*
>(this->
args() + fNumArgs); }
61void ChromeTracingTracer::createBlock() {
62 fCurBlock.fBlock = BlockPtr(
new uint8_t[kBlockSize]);
63 fCurBlock.fEventsInBlock = 0;
71 if (fCurBlockUsed +
size > kBlockSize) {
75 memcpy(fCurBlock.fBlock.get() + fCurBlockUsed,
data,
size);
76 Handle handle =
reinterpret_cast<Handle>(fCurBlock.fBlock.get() + fCurBlockUsed);
77 fCurBlockUsed +=
size;
78 fCurBlock.fEventsInBlock++;
83 const uint8_t* categoryEnabledFlag,
87 const char** argNames,
88 const uint8_t* argTypes,
89 const uint64_t* argValues,
95 int size =
static_cast<int>(
sizeof(
TraceEvent) + numArgs *
sizeof(TraceEventArg));
96 for (
int i = 0;
i < numArgs; ++
i) {
108 traceEvent->fPhase = phase;
109 traceEvent->fNumArgs = numArgs;
110 traceEvent->fSize =
size;
111 traceEvent->fName =
name;
112 traceEvent->fID =
id;
113 traceEvent->fClockBegin = std::chrono::steady_clock::now().time_since_epoch().count();
114 traceEvent->fClockEnd = 0;
117 TraceEventArg* traceEventArgs = traceEvent->args();
118 char* stringTableBase = traceEvent->stringTable();
119 char* stringTable = stringTableBase;
120 for (
int i = 0;
i < numArgs; ++
i) {
121 traceEventArgs[
i].fArgName = argNames[
i];
122 traceEventArgs[
i].fArgType = argTypes[
i];
125 traceEventArgs[
i].fArgValue = stringTable - stringTableBase;
130 *stringTable++ = *valueStr++;
134 traceEventArgs[
i].fArgValue = argValues[
i];
138 return this->appendEvent(storagePtr,
size);
147 traceEvent->fClockEnd = std::chrono::steady_clock::now().time_since_epoch().count();
153 const char* stringTableBase) {
175struct TraceEventSerializationState {
176 TraceEventSerializationState(uint64_t clockOffset)
177 : fClockOffset(clockOffset), fNextThreadID(0) {}
180 if (
int* shortIDPtr = fShortThreadIDMap.find(
id)) {
183 int shortID = fNextThreadID++;
184 fShortThreadIDMap.set(
id, shortID);
188 uint64_t fClockOffset;
198 TraceEventSerializationState* serializationState) {
201 auto baseTypeResolver = &(serializationState->fBaseTypeResolver);
203 SkASSERT(
nullptr == baseTypeResolver->find(traceEvent->fID));
204 baseTypeResolver->set(traceEvent->fID, traceEvent->fName);
206 SkASSERT(
nullptr != baseTypeResolver->find(traceEvent->fID));
207 baseTypeResolver->remove(traceEvent->fID);
214 if (0 != traceEvent->fID) {
216 writer->
appendPointer(
"id",
reinterpret_cast<void*
>(traceEvent->fID));
221 uint64_t relativeTimestamp =
222 static_cast<int64_t
>(traceEvent->fClockBegin - serializationState->fClockOffset);
223 writer->
appendDouble(
"ts",
static_cast<double>(relativeTimestamp) * 1
E-3);
224 if (0 != traceEvent->fClockEnd) {
225 double dur =
static_cast<double>(traceEvent->fClockEnd - traceEvent->fClockBegin) * 1
E-3;
229 writer->
appendS64(
"tid", serializationState->getShortThreadID(traceEvent->fThreadID));
234 if (traceEvent->fNumArgs) {
236 const char* stringTable = traceEvent->stringTable();
237 bool addedSnapshot =
false;
239 baseTypeResolver->find(traceEvent->fID) &&
240 0 != strcmp(*baseTypeResolver->find(traceEvent->fID), traceEvent->fName)) {
243 writer->
appendCString(
"base_type", *baseTypeResolver->find(traceEvent->fID));
244 addedSnapshot =
true;
247 for (
int i = 0;
i < traceEvent->fNumArgs; ++
i) {
248 const TraceEventArg* arg = traceEvent->args() +
i;
252 if (arg->fArgName &&
'#' == arg->fArgName[0]) {
272void ChromeTracingTracer::flush() {
278 SkDebugf(
"Failed to create directory.");
286 uint64_t clockOffset = 0;
287 if (fBlocks.
size() > 0) {
288 clockOffset =
reinterpret_cast<TraceEvent*
>(fBlocks[0].fBlock.get())->fClockBegin;
289 }
else if (fCurBlock.fEventsInBlock > 0) {
290 clockOffset =
reinterpret_cast<TraceEvent*
>(fCurBlock.fBlock.get())->fClockBegin;
293 TraceEventSerializationState serializationState(clockOffset);
296 const TraceEventBlock& block,
297 TraceEventSerializationState* serializationState) {
299 for (
int i = 0;
i < block.fEventsInBlock; ++
i) {
301 traceEvent = traceEvent->next();
305 for (
int i = 0;
i < fBlocks.
size(); ++
i) {
306 event_block_to_json(&writer, fBlocks[
i], &serializationState);
308 event_block_to_json(&writer, fCurBlock, &serializationState);
static void trace_event_to_json(SkJSONWriter *writer, TraceEvent *traceEvent, TraceEventSerializationState *serializationState)
static void trace_value_to_json(SkJSONWriter *writer, uint64_t argValue, uint8_t argType, const char *stringTableBase)
static float next(float f)
static constexpr T SkAlign8(T x)
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
bool sk_mkdir(const char *path)
bool sk_exists(const char *path, SkFILE_Flags=(SkFILE_Flags) 0)
SkThreadID SkGetThreadID()
#define TRACE_VALUE_TYPE_STRING
#define TRACE_VALUE_TYPE_BOOL
#define TRACE_VALUE_TYPE_POINTER
#define TRACE_VALUE_TYPE_COPY_STRING
#define TRACE_VALUE_TYPE_INT
#define TRACE_VALUE_TYPE_UINT
#define TRACE_VALUE_TYPE_DOUBLE
#define TRACE_EVENT_PHASE_SNAPSHOT_OBJECT
#define TRACE_EVENT_PHASE_CREATE_OBJECT
#define TRACE_EVENT_PHASE_DELETE_OBJECT
ChromeTracingTracer(const char *filename)
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
~ChromeTracingTracer() override
void updateTraceEventDuration(const uint8_t *categoryEnabledFlag, const char *name, SkEventTracer::Handle handle) override
void appendS32(int32_t value)
void appendNString(char const (&value)[N])
void appendDouble(double value)
void beginObject(const char *name=nullptr, bool multiline=true)
void appendU64(uint64_t value)
void appendPointer(const void *value)
void appendS64(int64_t value)
void appendBool(bool value)
void appendName(const char *name)
void appendCString(const char *value)
void appendString(const char *value, size_t size)
static SkString Dirname(const char *fullPath)
const char * c_str() const
FlutterSemanticsFlag flags
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
DEF_SWITCHES_START aot vmservice shared library name
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
void TraceEvent(TraceArg category, TraceArg name, size_t flow_id_count, const uint64_t *flow_ids, Args... args)
static const void * TraceValueAsPointer(uint64_t value)
static const char * TraceValueAsString(uint64_t value)
std::shared_ptr< const fml::Mapping > data