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

Side by Side Diff: gpu/command_buffer/service/gpu_tracer.cc

Issue 11416117: Hookup the GPUTrace events. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years 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) 2012 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 #include "gpu/command_buffer/service/gpu_tracer.h"
6
7 #include "base/threading/non_thread_safe.h"
8 #include "base/threading/thread.h"
9 #include "base/time.h"
10 #include "ui/gl/gl_bindings.h"
11
12 namespace gpu {
13 namespace gles2 {
14
15 class GPUTracer::Trace {
16 public:
17 virtual ~Trace() {};
18
19 virtual void Start() = 0;
20 virtual void End() = 0;
21
22 // True if the the results of this query are available.
23 virtual bool IsAvailable() = 0;
24
25 const char* name() {
26 return name_.c_str();
27 }
28
29 protected:
30 explicit Trace(const std::string& name) : name_(name) {}
31
32 virtual int64 start_time() = 0;
33 virtual int64 end_time() = 0;
34
35 private:
36 friend GPUTracer::Outputter;
jonathan.backer 2012/11/23 18:55:41 Why friend? To read the name? You could hide the T
dsinclair 2012/11/23 21:13:56 Friend'd to give access to the start_time and end_
37
38 std::string name_;
39
40 DISALLOW_COPY_AND_ASSIGN(Trace);
41 };
42
43 class GPUTracer::Outputter
44 : public base::Thread,
45 public base::NonThreadSafe {
jonathan.backer 2012/11/23 18:55:41 base::NonThreadSafe is for sanity checking that yo
dsinclair 2012/11/23 21:13:56 copy-paste. Removed.
46 public:
47 static linked_ptr<GPUTracer::Outputter> Create(const std::string& name) {
jonathan.backer 2012/11/23 18:55:41 Why a linked_ptr? And why a factory?
dsinclair 2012/11/23 21:13:56 Was half an implementation of something else. Chan
48 linked_ptr<GPUTracer::Outputter> out = linked_ptr<GPUTracer::Outputter>(
49 new GPUTracer::Outputter(name));
50
51 // We need to start/stop the thread in order to get a thread_id.
52 out->Start();
53 out->Stop();
54 return out;
55 }
56
57 virtual ~Outputter() {}
58
59 virtual void Output(GPUTracer::Trace* trace) {
60 // TODO(dsinclair): Change to TRACE_EVENT
61 LOG(INFO) << "Thread " << thread_id() << ": "
62 << thread_name() << ": "
63 << trace->name() << ": "
64 << trace_start_time(trace) << " "
65 << trace_end_time(trace);
66 }
67
68 protected:
69 explicit Outputter(const std::string& name) : base::Thread(name.c_str()) {
70 }
71
72
73 int64 trace_start_time(GPUTracer::Trace* trace) {
74 return trace->start_time();
75 }
76
77 int64 trace_end_time(GPUTracer::Trace* trace) {
78 return trace->end_time();
79 }
80
81 private:
82 DISALLOW_COPY_AND_ASSIGN(Outputter);
83 };
84
85 namespace {
86
87 static const unsigned int kGPUTraceMaxQueueSize = 1024;
88
89 class GPUTracerSystemTime : public GPUTracer {
90 public:
91 GPUTracerSystemTime();
92 ~GPUTracerSystemTime();
93
94 linked_ptr<GPUTracer::Trace> CreateTrace(const std::string& name) OVERRIDE;
95
96 private:
97 class Trace : public GPUTracer::Trace {
98 public:
99 explicit Trace(const std::string& name);
100 ~Trace() OVERRIDE;
101
102 void Start() OVERRIDE;
103 void End() OVERRIDE;
104 bool IsAvailable() OVERRIDE;
105
106 protected:
107 int64 start_time() OVERRIDE;
108 int64 end_time() OVERRIDE;
109
110 private:
111 bool has_ended_;
112 base::TimeTicks start_time_;
113 base::TimeTicks end_time_;
114
115 DISALLOW_COPY_AND_ASSIGN(Trace);
116 };
117
118 DISALLOW_COPY_AND_ASSIGN(GPUTracerSystemTime);
119 };
120
121 class GPUTracerARBTimerQuery : public GPUTracer {
122 public:
123 GPUTracerARBTimerQuery();
124 ~GPUTracerARBTimerQuery();
125
126 linked_ptr<GPUTracer::Trace> CreateTrace(const std::string& name) OVERRIDE;
127
128 private:
129 class Trace : public GPUTracer::Trace {
130 public:
131 explicit Trace(const std::string& name);
132 ~Trace() OVERRIDE;
133
134 void Start() OVERRIDE;
135 void End() OVERRIDE;
136 bool IsAvailable() OVERRIDE;
137
138 protected:
139 int64 start_time() OVERRIDE;
140 int64 end_time() OVERRIDE;
141
142 private:
143 unsigned int start_timer_;
144 unsigned int end_timer_;
145
146 DISALLOW_COPY_AND_ASSIGN(Trace);
147 };
148
149 class Outputter : public GPUTracer::Outputter {
150 public:
151 static linked_ptr<GPUTracer::Outputter> Create(const std::string& name,
152 int64 timer_offset) {
153 linked_ptr<GPUTracer::Outputter> out = linked_ptr<GPUTracer::Outputter>(
154 new GPUTracerARBTimerQuery::Outputter(name, timer_offset));
155
156 // We need to start/stop the thread in order to get a thread_id.
157 out->Start();
158 out->Stop();
159 return out;
160 }
161
162 ~Outputter() {}
163
164 void Output(GPUTracer::Trace* trace) OVERRIDE {
165 // TODO(dsinclair): Change to TRACE_EVENT
166 LOG(INFO) << "Thread " << thread_id() << ": "
167 << thread_name() << ": "
168 << trace->name() << ": "
169 << trace_start_time(trace) << " "
170 << trace_end_time(trace);
171 }
172
173 protected:
174 explicit Outputter(const std::string& name, int64 timer_offset)
175 : GPUTracer::Outputter(name.c_str()),
176 timer_offset_(timer_offset) {
177 }
178
179 int64 trace_start_time(GPUTracer::Trace* trace) {
180 return GPUTracer::Outputter::trace_start_time(trace) + timer_offset_;
181 }
182
183 int64 trace_end_time(GPUTracer::Trace* trace) {
184 return GPUTracer::Outputter::trace_end_time(trace) + timer_offset_;
185 }
186
187 private:
188 int64 timer_offset_;
189
190 DISALLOW_COPY_AND_ASSIGN(Outputter);
191 };
192
193 DISALLOW_COPY_AND_ASSIGN(GPUTracerARBTimerQuery);
194 };
195
196 GPUTracerSystemTime::GPUTracerSystemTime() : GPUTracer() {
197 output_ = linked_ptr<GPUTracer::Outputter>(
198 GPUTracer::Outputter::Create("SystemTime"));
199 }
200
201 GPUTracerSystemTime::~GPUTracerSystemTime() {
202 }
203
204 linked_ptr<GPUTracer::Trace> GPUTracerSystemTime::CreateTrace(
205 const std::string& name) {
206 return linked_ptr<GPUTracer::Trace>(new GPUTracerSystemTime::Trace(name));
207 }
208
209 GPUTracerSystemTime::Trace::Trace(const std::string& name) :
210 GPUTracer::Trace(name),
211 has_ended_(false),
212 start_time_(),
213 end_time_() {
214 }
215
216 GPUTracerSystemTime::Trace::~Trace() {
217 }
218
219 void GPUTracerSystemTime::Trace::Start() {
220 start_time_ = base::TimeTicks::NowFromSystemTraceTime();
221 }
222
223 int64 GPUTracerSystemTime::Trace::start_time() {
224 return start_time_.ToInternalValue();
225 }
226
227 void GPUTracerSystemTime::Trace::End() {
228 end_time_ = base::TimeTicks::NowFromSystemTraceTime();
229 has_ended_ = true;
230 }
231
232 int64 GPUTracerSystemTime::Trace::end_time() {
233 return end_time_.ToInternalValue();
234 }
235
236 bool GPUTracerSystemTime::Trace::IsAvailable() {
237 return has_ended_;
238 }
239
240 GPUTracerARBTimerQuery::GPUTracerARBTimerQuery() : GPUTracer() {
241 // TODO(dsinclair): Change to glGetInteger64v.
242 GLuint64 gl_now = 0;
243 GLuint query;
244 glGenQueries(1, &query);
245
246 // Flush the pipeline so our query is more accurate.
247 glFinish();
248
249 glQueryCounter(query, GL_TIMESTAMP);
250 glGetQueryObjectui64v(query, GL_QUERY_RESULT, &gl_now);
251 glDeleteQueries(1, &query);
252
253 gl_now /= base::Time::kNanosecondsPerMicrosecond;
254
255 base::TimeTicks system_now = base::TimeTicks::NowFromSystemTraceTime();
256
257 int64 time_offset = system_now.ToInternalValue() - gl_now;
258 output_ = linked_ptr<GPUTracer::Outputter>(
259 GPUTracerARBTimerQuery::Outputter::Create("GL_ARB_timer_query",
260 time_offset));
261 }
262
263 GPUTracerARBTimerQuery::~GPUTracerARBTimerQuery() {
264 }
265
266 linked_ptr<GPUTracer::Trace> GPUTracerARBTimerQuery::CreateTrace(
267 const std::string& name) {
268 return linked_ptr<GPUTracer::Trace>(new GPUTracerARBTimerQuery::Trace(name));
269 }
270
271 GPUTracerARBTimerQuery::Trace::Trace(const std::string& name) :
272 GPUTracer::Trace(name),
273 start_timer_(0),
274 end_timer_(0) {
275 GLuint queries[2];
276 glGenQueries(2, queries);
277
278 start_timer_ = queries[0];
279 end_timer_ = queries[1];
280 }
281
282 GPUTracerARBTimerQuery::Trace::~Trace() {
283 GLuint queries[] = {start_timer_, end_timer_};
284 glDeleteQueries(2, queries);
285 }
286
287 void GPUTracerARBTimerQuery::Trace::Start() {
288 glQueryCounter(start_timer_, GL_TIMESTAMP);
289 }
290
291 int64 GPUTracerARBTimerQuery::Trace::start_time() {
292 GLint64 timestamp;
293 glGetQueryObjecti64v(start_timer_, GL_QUERY_RESULT, &timestamp);
294 return timestamp / base::Time::kNanosecondsPerMicrosecond;
295 }
296
297 void GPUTracerARBTimerQuery::Trace::End() {
298 glQueryCounter(end_timer_, GL_TIMESTAMP);
299 }
300
301 int64 GPUTracerARBTimerQuery::Trace::end_time() {
302 GLint64 timestamp;
303 glGetQueryObjecti64v(end_timer_, GL_QUERY_RESULT, &timestamp);
304 return timestamp / base::Time::kNanosecondsPerMicrosecond;
305 }
306
307 bool GPUTracerARBTimerQuery::Trace::IsAvailable() {
308 GLint done = 0;
309 glGetQueryObjectiv(end_timer_, GL_QUERY_RESULT_AVAILABLE, &done);
310 return !!done;
311 }
312
313 } // namespace
314
315 scoped_ptr<GPUTracer> GPUTracer::create() {
316 if (gfx::g_driver_gl.ext.b_GL_ARB_timer_query)
317 return scoped_ptr<GPUTracer>(new GPUTracerARBTimerQuery());
318
319 return scoped_ptr<GPUTracer>(new GPUTracerSystemTime());
320 }
321
322 GPUTracer::GPUTracer() {
323 }
324
325 GPUTracer::~GPUTracer() {
326 }
327
328 bool GPUTracer::Begin(const std::string& name) {
329 // Make sure we are not nesting trace commands.
330 if (current_trace_.get() != NULL)
331 return false;
332
333 current_trace_ = CreateTrace(name);
334 current_trace_->Start();
335 return true;
336 }
337
338 bool GPUTracer::End() {
339 if (current_trace_.get() == NULL) {
340 return false;
341 }
342
343 current_trace_->End();
344 traces_.push_back(current_trace_);
345 current_trace_ = linked_ptr<GPUTracer::Trace>(NULL);
jonathan.backer 2012/11/23 18:55:41 I think that you can just call .reset() here.
dsinclair 2012/11/23 21:13:56 Done.
346
347 if (traces_.size() > kGPUTraceMaxQueueSize)
348 Process();
349
350 return true;
351 }
352
353 void GPUTracer::Process() {
354 while (!traces_.empty() && traces_.front()->IsAvailable()) {
355 output_->Output(traces_.front().get());
356 traces_.pop_front();
357 }
358 }
359
360 } // namespace gles2
361 } // namespace gpu
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698