Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1071)

Side by Side Diff: gpu/common/gpu_trace_event.h

Issue 6691013: Introduce gpu_trace_event for gpu performance analysis. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Trace events are for tracking application performance.
6 //
7 // Events are issued against categories. Whereas LOG's
8 // categories are statically defined, TRACE categories are created
9 // implicitly with a string. For example:
10 // GPU_TRACE_EVENT_INSTANT0("MY_SUBSYSTEM", "SomeImportantEvent")
11 //
12 // Events can be INSTANT, or can be pairs of BEGIN and END:
13 // GPU_TRACE_EVENT_BEGIN0("MY_SUBSYSTEM", "SomethingCostly")
14 // doSomethingCostly()
15 // GPU_TRACE_EVENT_END0("MY_SUBSYSTEM", "SomethingCostly")
16 //
17 // A common use case is to trace entire function scopes. This
18 // issues a trace BEGIN and END automatically:
19 // void doSomethingCostly() {
20 // GPU_TRACE_EVENT0("MY_SUBSYSTEM", "doSomethingCostly");
21 // ...
22 // }
23 //
24 // Additional parameters can be associated with an event:
25 // void doSomethingCostly2(int howMuch) {
26 // GPU_TRACE_EVENT1("MY_SUBSYSTEM", "doSomethingCostly",
27 // "howMuch", StringPrintf("%i", howMuch).c_str());
28 // ...
29 // }
30 //
31 // The trace system will automatically add to this information the
32 // current process id, thread id, a timestamp down to the
33 // microsecond, as well as the file and line number of the calling location.
34 //
35 // By default, trace collection is compiled in, but turned off at runtime.
36 // Collecting trace data is the responsibility of the embedding
37 // application. In Chrome's case, navigating to about:gpu will turn on
38 // tracing and display data collected across all active processes.
39 //
40
41 #ifndef GPU_TRACE_EVENT_H_
42 #define GPU_TRACE_EVENT_H_
43 #pragma once
44
45 #include "build/build_config.h"
46
47 #include <string>
48
49 #include "base/scoped_ptr.h"
50 #include "base/scoped_vector.h"
51 #include "base/atomicops.h"
52 #include "base/singleton.h"
53 #include "base/time.h"
54 #include "base/timer.h"
55 #include "base/callback.h"
56 #include <vector>
57
58
59 // Implementation detail: trace event macros create temporary variables
60 // to keep instrumentation overhead low. These macros give each temporary
61 // variable a unique name based on the line number to prevent name collissions.
62 #define GPU_TRACE_EVENT_UNIQUE_IDENTIFIER3(a,b) a##b
63 #define GPU_TRACE_EVENT_UNIQUE_IDENTIFIER2(a,b) \
64 GPU_TRACE_EVENT_UNIQUE_IDENTIFIER3(a,b)
65 #define GPU_TRACE_EVENT_UNIQUE_IDENTIFIER(name_prefix) \
66 GPU_TRACE_EVENT_UNIQUE_IDENTIFIER2(name_prefix, __LINE__)
67
68 // Records a pair of begin and end events called "name" for the current
69 // scope, with 0, 1 or 2 associated arguments. If the category is not
70 // enabled, then this does nothing.
71 #define GPU_TRACE_EVENT0(category, name) \
72 GPU_TRACE_EVENT1(category, name, NULL, NULL)
73 #define GPU_TRACE_EVENT1(category, name, arg1name, arg1val) \
74 GPU_TRACE_EVENT2(category, name, arg1name, arg1val, NULL, NULL)
75 #define GPU_TRACE_EVENT2(category, name, arg1name, arg1val, arg2name, arg2val) \
76 static gpu::TraceCategory* \
77 GPU_TRACE_EVENT_UNIQUE_IDENTIFIER(catstatic) = \
78 gpu::TraceLog::GetInstance()->GetCategory(category); \
79 if (base::subtle::Acquire_Load(\
80 &(GPU_TRACE_EVENT_UNIQUE_IDENTIFIER(catstatic))->enabled_)) { \
81 gpu::TraceLog::GetInstance()->AddTraceEvent( \
82 gpu::GPU_TRACE_EVENT_PHASE_BEGIN, \
83 __FILE__, __LINE__, \
84 GPU_TRACE_EVENT_UNIQUE_IDENTIFIER(catstatic), \
85 name, \
86 arg1name, arg1val, \
87 arg2name, arg2val); \
88 } \
89 gpu::internal::TraceEndOnScopeClose __profileScope ## __LINE ( \
90 __FILE__, __LINE__, \
91 GPU_TRACE_EVENT_UNIQUE_IDENTIFIER(catstatic), name);
92
93 // Records a single event called "name" immediately, with 0, 1 or 2
94 // associated arguments. If the category is not enabled, then this
95 // does nothing.
96 #define GPU_TRACE_EVENT_INSTANT0(category, name) \
97 GPU_TRACE_EVENT_INSTANT1(category, name, NULL, NULL)
98 #define GPU_TRACE_EVENT_INSTANT1(category, name, arg1name, arg1val) \
99 GPU_TRACE_EVENT_INSTANT2(category, name, arg1name, arg1val, NULL, NULL)
100 #define GPU_TRACE_EVENT_INSTANT2(category, name, arg1name, arg1val, \
101 arg2name, arg2val) \
102 static gpu::TraceCategory* \
103 GPU_TRACE_EVENT_UNIQUE_IDENTIFIER(catstatic) = \
104 gpu::TraceLog::GetInstance()->GetCategory(category); \
105 if (base::subtle::Acquire_Load( \
106 &(GPU_TRACE_EVENT_UNIQUE_IDENTIFIER(catstatic))->enabled_)) { \
107 gpu::TraceLog::GetInstance()->AddTraceEvent( \
108 gpu::GPU_TRACE_EVENT_PHASE_INSTANT, \
109 __FILE__, __LINE__, \
110 GPU_TRACE_EVENT_UNIQUE_IDENTIFIER(catstatic), \
111 name, \
112 arg1name, arg1val, \
113 arg2name, arg2val); \
114 }
115
116 // Records a single BEGIN event called "name" immediately, with 0, 1 or 2
117 // associated arguments. If the category is not enabled, then this
118 // does nothing.
119 #define GPU_TRACE_EVENT_BEGIN0(category, name) \
120 GPU_TRACE_EVENT_BEGIN1(category, name, NULL, NULL)
121 #define GPU_TRACE_EVENT_BEGIN1(category, name, arg1name, arg1val) \
122 GPU_TRACE_EVENT_BEGIN2(category, name, arg1name, arg1val, NULL, NULL)
123 #define GPU_TRACE_EVENT_BEGIN2(category, name, arg1name, arg1val, \
124 arg2name, arg2val) \
125 static gpu::TraceCategory* \
126 GPU_TRACE_EVENT_UNIQUE_IDENTIFIER(catstatic) = \
127 gpu::TraceLog::GetInstance()->GetCategory(category); \
128 if (base::subtle::Acquire_Load( \
129 &(GPU_TRACE_EVENT_UNIQUE_IDENTIFIER(catstatic))->enabled_)) { \
130 gpu::TraceLog::GetInstance()->AddTraceEvent( \
131 gpu::GPU_TRACE_EVENT_PHASE_BEGIN, \
132 __FILE__, __LINE__, \
133 GPU_TRACE_EVENT_UNIQUE_IDENTIFIER(catstatic), \
134 name, \
135 arg1name, arg1val, \
136 arg2name, arg2val); \
137 }
138
139 // Records a single END event for "name" immediately. If the category
140 // is not enabled, then this does nothing.
141 #define GPU_TRACE_EVENT_END0(category, name) \
142 static gpu::TraceCategory* \
143 GPU_TRACE_EVENT_UNIQUE_IDENTIFIER(catstatic) = \
144 gpu::TraceLog::GetInstance()->GetCategory(category); \
145 if (base::subtle::Acquire_Load( \
146 &(GPU_TRACE_EVENT_UNIQUE_IDENTIFIER(catstatic))->enabled_)) { \
147 gpu::TraceLog::GetInstance()->AddTraceEvent( \
148 gpu::GPU_TRACE_EVENT_PHASE_END, \
149 __FILE__, __LINE__, \
150 GPU_TRACE_EVENT_UNIQUE_IDENTIFIER(catstatic), \
151 name, \
152 arg1name, arg1val, \
153 arg2name, arg2val); \
154 }
155
156
157 namespace gpu {
158
159 // Categories allow enabling/disabling of streams of trace events
160 // Don't manipulate the category object directly, as this may lead
161 // to threading issues. Use the TraceLog methods instead.
162 class TraceCategory {
163 public:
164 TraceCategory(const char* name, bool enabled);
165 ~TraceCategory();
166
167 const char* name() const { return name_; }
168
169 // NEVER read these directly, let the macros do it for you
170 volatile base::subtle::Atomic32 enabled_;
171 protected:
172 const char* name_;
173 };
174
175 #define TRACE_MAX_NUM_ARGS 2
176
177 enum TraceEventPhase {
178 GPU_TRACE_EVENT_PHASE_BEGIN,
179 GPU_TRACE_EVENT_PHASE_END,
180 GPU_TRACE_EVENT_PHASE_INSTANT
181 };
182
183 // Output records are "Events" and can be obtained via the
184 // OutputCallback whenever the logging system decides to flush. This
185 // can happen at any time, on any thread, or you can programatically
186 // force it to happen.
187 struct TraceEvent {
188 static void AppendAsJSON(std::string* out,
189 const std::vector<TraceEvent>& events);
190 void AppendAsJSON(std::string* out) const;
191
192
193 unsigned long processId;
194 unsigned long threadId;
195 base::TimeTicks timestamp;
196 TraceEventPhase phase;
197 TraceCategory* category;
198 const char* name;
199 const char* argNames[TRACE_MAX_NUM_ARGS];
200 std::string argValues[TRACE_MAX_NUM_ARGS];
201 };
202
203
204 class TraceLog {
205 public:
206
greggman 2011/03/15 00:19:50 remove this line blank (try gcl lint cl)
207 static TraceLog* GetInstance();
208
209 // Global enable of tracing. Currently enables all categories or not.
210 // TODO(nduca) Replaced with an Enable/DisableCategory() that
211 // implicitly controls the global logging state.
212 void SetEnabled(bool enabled);
213
214 // When enough events are collected, they are handed (in bulk) to
215 // the output callback. If no callback is set, the output will be
216 // silently dropped.
217 typedef Callback1<const std::string& /* json_events */>::Type OutputCallback;
218 void SetOutputCallback(OutputCallback* cb);
219
220 // Forwards data collected by a child process to the registered
221 // output callback.
222 void AddRemotelyCollectedData(const std::string& json_events);
223
224 // Flushes all logged data to the callback.
225 void Flush();
226
227 // Called by GPU_TRACE_EVENT* macros, don't call this directly.
228 TraceCategory* GetCategory(const char* name);
229
230 // Called by GPU_TRACE_EVENT* macros, don't call this directly.
231 void AddTraceEvent(TraceEventPhase phase,
232 const char* file, int line,
233 TraceCategory* category,
234 const char* name,
235 const char* arg1name, const char* arg1val,
236 const char* arg2name, const char* arg2val);
237
238 private:
239 // This allows constructor and destructor to be private and usable only
240 // by the Singleton class.
241 friend struct StaticMemorySingletonTraits<TraceLog>;
242
243 TraceLog();
244 ~TraceLog();
245 void FlushWithLockAlreadyHeld();
246
247 // TODO(nduca): switch to per-thread tace buffers to reduce thread
greggman 2011/03/15 00:19:50 tace -> trace
nduca 2011/03/15 01:21:40 Done.
248 // synchronization.
249 base::Lock lock_;
250 bool enabled_;
251 ScopedVector<TraceCategory> categories_;
252 scoped_ptr<OutputCallback> output_callback_;
253 std::vector<TraceEvent> logged_events_;
254
255 DISALLOW_COPY_AND_ASSIGN(TraceLog);
256 };
257
258 namespace internal {
259
260 // Used by GPU_TRACE_EVENTx macro. Do not use directly.
261 class TraceEndOnScopeClose {
262 public:
263 TraceEndOnScopeClose(const char* file, int line,
264 TraceCategory* category,
265 const char* name)
266 : file_(file)
267 , line_(line)
268 , category_(category)
269 , name_(name) { }
270
271 ~TraceEndOnScopeClose() {
272 if (base::subtle::Acquire_Load(&category_->enabled_))
273 gpu::TraceLog::GetInstance()->AddTraceEvent(
274 gpu::GPU_TRACE_EVENT_PHASE_END,
275 file_, line_,
276 category_,
277 name_,
278 NULL, NULL, NULL, NULL);
279 }
280
281 private:
282 const char* file_;
283 int line_;
284 TraceCategory* category_;
285 const char* name_;
286 };
287
288 } // namespace internal
289
290 } // namespace gpu
291
292 #endif // GPU_TRACE_EVENT_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698