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

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

Issue 6862002: Merge gpu_trace_event back into base/debug/trace_event (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: "fix gpu/command_buffer/client/cmd_buffer_helper to new macros" Created 9 years, 8 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) 2011 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/memory/scoped_ptr.h"
50 #include "base/atomicops.h"
51 #include "base/memory/scoped_vector.h"
52 #include "base/memory/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 NULL, NULL, \
153 NULL, NULL); \
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 size_t start,
191 size_t count);
192 TraceEvent();
193 ~TraceEvent();
194 void AppendAsJSON(std::string* out) const;
195
196
197 unsigned long processId;
198 unsigned long threadId;
199 base::TimeTicks timestamp;
200 TraceEventPhase phase;
201 TraceCategory* category;
202 const char* name;
203 const char* argNames[TRACE_MAX_NUM_ARGS];
204 std::string argValues[TRACE_MAX_NUM_ARGS];
205 };
206
207
208 class TraceLog {
209 public:
210 static TraceLog* GetInstance();
211
212 // Global enable of tracing. Currently enables all categories or not.
213 // TODO(nduca) Replaced with an Enable/DisableCategory() that
214 // implicitly controls the global logging state.
215 void SetEnabled(bool enabled);
216
217 // When enough events are collected, they are handed (in bulk) to
218 // the output callback. If no callback is set, the output will be
219 // silently dropped.
220 typedef Callback1<const std::string& /* json_events */>::Type OutputCallback;
221 void SetOutputCallback(OutputCallback* cb);
222
223 // Forwards data collected by a child process to the registered
224 // output callback.
225 void AddRemotelyCollectedData(const std::string& json_events);
226
227 // Flushes all logged data to the callback.
228 void Flush();
229
230 // Called by GPU_TRACE_EVENT* macros, don't call this directly.
231 TraceCategory* GetCategory(const char* name);
232
233 // Called by GPU_TRACE_EVENT* macros, don't call this directly.
234 void AddTraceEvent(TraceEventPhase phase,
235 const char* file, int line,
236 TraceCategory* category,
237 const char* name,
238 const char* arg1name, const char* arg1val,
239 const char* arg2name, const char* arg2val);
240
241 private:
242 // This allows constructor and destructor to be private and usable only
243 // by the Singleton class.
244 friend struct StaticMemorySingletonTraits<TraceLog>;
245
246 TraceLog();
247 ~TraceLog();
248 void FlushWithLockAlreadyHeld();
249
250 // TODO(nduca): switch to per-thread trace buffers to reduce thread
251 // synchronization.
252 base::Lock lock_;
253 bool enabled_;
254 ScopedVector<TraceCategory> categories_;
255 scoped_ptr<OutputCallback> output_callback_;
256 std::vector<TraceEvent> logged_events_;
257
258 DISALLOW_COPY_AND_ASSIGN(TraceLog);
259 };
260
261 namespace internal {
262
263 // Used by GPU_TRACE_EVENTx macro. Do not use directly.
264 class TraceEndOnScopeClose {
265 public:
266 TraceEndOnScopeClose(const char* file, int line,
267 TraceCategory* category,
268 const char* name)
269 : file_(file)
270 , line_(line)
271 , category_(category)
272 , name_(name) { }
273
274 ~TraceEndOnScopeClose() {
275 if (base::subtle::Acquire_Load(&category_->enabled_))
276 gpu::TraceLog::GetInstance()->AddTraceEvent(
277 gpu::GPU_TRACE_EVENT_PHASE_END,
278 file_, line_,
279 category_,
280 name_,
281 NULL, NULL, NULL, NULL);
282 }
283
284 private:
285 const char* file_;
286 int line_;
287 TraceCategory* category_;
288 const char* name_;
289 };
290
291 } // namespace internal
292
293 } // namespace gpu
294
295 #endif // GPU_TRACE_EVENT_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698