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 #ifndef ChromeTracingTracer_DEFINED
9 #define ChromeTracingTracer_DEFINED
10 
11 #include "include/core/SkString.h"
12 #include "include/private/SkSpinlock.h"
13 #include "include/private/SkTHash.h"
14 #include "include/utils/SkEventTracer.h"
15 #include "tools/trace/EventTracingPriv.h"
16 
17 class SkJSONWriter;
18 
19 /**
20  * A SkEventTracer implementation that logs events to JSON for viewing with chrome://tracing.
21  */
22 class ChromeTracingTracer : public SkEventTracer {
23 public:
24     ChromeTracingTracer(const char* filename);
25     ~ChromeTracingTracer() override;
26 
27     SkEventTracer::Handle addTraceEvent(char            phase,
28                                         const uint8_t*  categoryEnabledFlag,
29                                         const char*     name,
30                                         uint64_t        id,
31                                         int             numArgs,
32                                         const char**    argNames,
33                                         const uint8_t*  argTypes,
34                                         const uint64_t* argValues,
35                                         uint8_t         flags) override;
36 
37     void updateTraceEventDuration(const uint8_t*        categoryEnabledFlag,
38                                   const char*           name,
39                                   SkEventTracer::Handle handle) override;
40 
getCategoryGroupEnabled(const char * name)41     const uint8_t* getCategoryGroupEnabled(const char* name) override {
42         return fCategories.getCategoryGroupEnabled(name);
43     }
44 
getCategoryGroupName(const uint8_t * categoryEnabledFlag)45     const char* getCategoryGroupName(const uint8_t* categoryEnabledFlag) override {
46         return fCategories.getCategoryGroupName(categoryEnabledFlag);
47     }
48 
49 private:
50     void flush();
51 
52     enum {
53         // Events are variable size, but most commonly 48 bytes, assuming 64-bit pointers and
54         // reasonable packing. This is a first guess at a number that balances memory usage vs.
55         // time overhead of allocating blocks.
56         kBlockSize = 512 * 1024,
57     };
58 
59     typedef std::unique_ptr<uint8_t[]> BlockPtr;
60     struct TraceEventBlock {
61         BlockPtr fBlock;
62         int      fEventsInBlock;
63     };
64 
65     void createBlock();
66 
67     Handle appendEvent(const void* data, size_t size);
68 
69     SkString                 fFilename;
70     SkSpinlock               fMutex;
71     SkEventTracingCategories fCategories;
72 
73     TraceEventBlock fCurBlock;
74     size_t          fCurBlockUsed;
75 
76     SkTArray<TraceEventBlock> fBlocks;
77 };
78 
79 #endif
80