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

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

Issue 776603003: Changed the GPU Tracer so the category names can be customized. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Service side GPU trace not turned on when device is turned on Created 6 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "gpu/command_buffer/service/gpu_tracer.h" 5 #include "gpu/command_buffer/service/gpu_tracer.h"
6 6
7 #include <deque> 7 #include <deque>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/debug/trace_event.h" 10 #include "base/debug/trace_event.h"
11 #include "base/strings/string_util.h" 11 #include "base/strings/string_util.h"
12 #include "base/time/time.h" 12 #include "base/time/time.h"
13 #include "gpu/command_buffer/common/gles2_cmd_utils.h" 13 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
14 14
15 namespace gpu { 15 namespace gpu {
16 namespace gles2 { 16 namespace gles2 {
17 17
18 static const unsigned int kProcessInterval = 16; 18 static const unsigned int kProcessInterval = 16;
19 static TraceOutputter* g_outputter_thread = NULL; 19 static TraceOutputter* g_outputter_thread = NULL;
20 20
21 TraceMarker::TraceMarker(const std::string& name) 21 TraceMarker::TraceMarker(const std::string& category, const std::string& name)
22 : name_(name), 22 : category_(category),
23 name_(name),
23 trace_(NULL) { 24 trace_(NULL) {
24 } 25 }
25 26
26 TraceMarker::~TraceMarker() { 27 TraceMarker::~TraceMarker() {
27 } 28 }
28 29
29 scoped_refptr<TraceOutputter> TraceOutputter::Create(const std::string& name) { 30 scoped_refptr<TraceOutputter> TraceOutputter::Create(const std::string& name) {
30 if (!g_outputter_thread) { 31 if (!g_outputter_thread) {
31 g_outputter_thread = new TraceOutputter(name); 32 g_outputter_thread = new TraceOutputter(name);
32 } 33 }
33 return g_outputter_thread; 34 return g_outputter_thread;
34 } 35 }
35 36
36 TraceOutputter::TraceOutputter(const std::string& name) 37 TraceOutputter::TraceOutputter(const std::string& name)
37 : named_thread_(name.c_str()), local_trace_id_(0) { 38 : named_thread_(name.c_str()), local_trace_id_(0) {
38 named_thread_.Start(); 39 named_thread_.Start();
39 named_thread_.Stop(); 40 named_thread_.Stop();
40 } 41 }
41 42
42 TraceOutputter::~TraceOutputter() { g_outputter_thread = NULL; } 43 TraceOutputter::~TraceOutputter() { g_outputter_thread = NULL; }
43 44
44 void TraceOutputter::Trace(const std::string& name, 45 void TraceOutputter::Trace(const std::string& category,
46 const std::string& name,
45 int64 start_time, 47 int64 start_time,
46 int64 end_time) { 48 int64 end_time) {
47 TRACE_EVENT_COPY_BEGIN_WITH_ID_TID_AND_TIMESTAMP0( 49 TRACE_EVENT_COPY_BEGIN_WITH_ID_TID_AND_TIMESTAMP0(category.c_str(),
48 TRACE_DISABLED_BY_DEFAULT("gpu.device"), 50 name.c_str(),
49 name.c_str(), 51 local_trace_id_,
50 local_trace_id_, 52 named_thread_.thread_id(),
51 named_thread_.thread_id(), 53 start_time);
52 start_time); 54 TRACE_EVENT_COPY_END_WITH_ID_TID_AND_TIMESTAMP0(category.c_str(),
53 TRACE_EVENT_COPY_END_WITH_ID_TID_AND_TIMESTAMP0( 55 name.c_str(),
54 TRACE_DISABLED_BY_DEFAULT("gpu.device"), 56 local_trace_id_,
55 name.c_str(), 57 named_thread_.thread_id(),
56 local_trace_id_, 58 end_time);
57 named_thread_.thread_id(),
58 end_time);
59 ++local_trace_id_; 59 ++local_trace_id_;
60 } 60 }
61 61
62 GPUTrace::GPUTrace(scoped_refptr<Outputter> outputter, 62 GPUTrace::GPUTrace(scoped_refptr<Outputter> outputter,
63 const std::string& category,
63 const std::string& name, 64 const std::string& name,
64 int64 offset, 65 int64 offset,
65 GpuTracerType tracer_type) 66 GpuTracerType tracer_type)
66 : name_(name), 67 : category_(category),
68 name_(name),
67 outputter_(outputter), 69 outputter_(outputter),
68 offset_(offset), 70 offset_(offset),
69 start_time_(0), 71 start_time_(0),
70 end_time_(0), 72 end_time_(0),
71 tracer_type_(tracer_type), 73 tracer_type_(tracer_type),
72 end_requested_(false) { 74 end_requested_(false) {
73 memset(queries_, 0, sizeof(queries_)); 75 memset(queries_, 0, sizeof(queries_));
74 switch (tracer_type_) { 76 switch (tracer_type_) {
75 case kTracerTypeARBTimer: 77 case kTracerTypeARBTimer:
76 case kTracerTypeDisjointTimer: 78 case kTracerTypeDisjointTimer:
(...skipping 10 matching lines...) Expand all
87 case kTracerTypeInvalid: 89 case kTracerTypeInvalid:
88 break; 90 break;
89 91
90 case kTracerTypeARBTimer: 92 case kTracerTypeARBTimer:
91 case kTracerTypeDisjointTimer: 93 case kTracerTypeDisjointTimer:
92 glDeleteQueriesARB(2, queries_); 94 glDeleteQueriesARB(2, queries_);
93 break; 95 break;
94 } 96 }
95 } 97 }
96 98
97 void GPUTrace::Start() { 99 void GPUTrace::Start(bool trace_service) {
98 TRACE_EVENT_COPY_ASYNC_BEGIN0( 100 if (trace_service) {
99 TRACE_DISABLED_BY_DEFAULT("gpu.service"), name().c_str(), this); 101 TRACE_EVENT_COPY_ASYNC_BEGIN0(category().c_str(), name().c_str(), this);
102 }
100 103
101 switch (tracer_type_) { 104 switch (tracer_type_) {
102 case kTracerTypeInvalid: 105 case kTracerTypeInvalid:
103 break; 106 break;
104 107
105 case kTracerTypeDisjointTimer: 108 case kTracerTypeDisjointTimer:
106 // For the disjoint timer, GPU idle time does not seem to increment the 109 // For the disjoint timer, GPU idle time does not seem to increment the
107 // internal counter. We must calculate the offset before any query. The 110 // internal counter. We must calculate the offset before any query. The
108 // good news is any device that supports disjoint timer will also support 111 // good news is any device that supports disjoint timer will also support
109 // glGetInteger64v, so we can query it directly unlike the ARBTimer case. 112 // glGetInteger64v, so we can query it directly unlike the ARBTimer case.
110 // The "offset_" variable will always be 0 during normal use cases, only 113 // The "offset_" variable will always be 0 during normal use cases, only
111 // under the unit tests will it be set to specific test values. 114 // under the unit tests will it be set to specific test values.
112 if (offset_ == 0) { 115 if (offset_ == 0) {
113 GLint64 gl_now = 0; 116 GLint64 gl_now = 0;
114 glGetInteger64v(GL_TIMESTAMP, &gl_now); 117 glGetInteger64v(GL_TIMESTAMP, &gl_now);
115 offset_ = base::TimeTicks::NowFromSystemTraceTime().ToInternalValue() - 118 offset_ = base::TimeTicks::NowFromSystemTraceTime().ToInternalValue() -
116 gl_now / base::Time::kNanosecondsPerMicrosecond; 119 gl_now / base::Time::kNanosecondsPerMicrosecond;
117 } 120 }
118 // Intentionally fall through to kTracerTypeARBTimer case.xs 121 // Intentionally fall through to kTracerTypeARBTimer case.xs
119 case kTracerTypeARBTimer: 122 case kTracerTypeARBTimer:
120 // GL_TIMESTAMP and GL_TIMESTAMP_EXT both have the same value. 123 // GL_TIMESTAMP and GL_TIMESTAMP_EXT both have the same value.
121 glQueryCounter(queries_[0], GL_TIMESTAMP); 124 glQueryCounter(queries_[0], GL_TIMESTAMP);
122 break; 125 break;
123 } 126 }
124 } 127 }
125 128
126 void GPUTrace::End() { 129 void GPUTrace::End(bool tracing_service) {
127 end_requested_ = true; 130 end_requested_ = true;
128 switch (tracer_type_) { 131 switch (tracer_type_) {
129 case kTracerTypeInvalid: 132 case kTracerTypeInvalid:
130 break; 133 break;
131 134
132 case kTracerTypeARBTimer: 135 case kTracerTypeARBTimer:
133 case kTracerTypeDisjointTimer: 136 case kTracerTypeDisjointTimer:
134 // GL_TIMESTAMP and GL_TIMESTAMP_EXT both have the same value. 137 // GL_TIMESTAMP and GL_TIMESTAMP_EXT both have the same value.
135 glQueryCounter(queries_[1], GL_TIMESTAMP); 138 glQueryCounter(queries_[1], GL_TIMESTAMP);
136 break; 139 break;
137 } 140 }
138 141
139 TRACE_EVENT_COPY_ASYNC_END0( 142 if (tracing_service) {
140 TRACE_DISABLED_BY_DEFAULT("gpu.service"), name().c_str(), this); 143 TRACE_EVENT_COPY_ASYNC_END0(category().c_str(), name().c_str(), this);
144 }
141 } 145 }
142 146
143 bool GPUTrace::IsAvailable() { 147 bool GPUTrace::IsAvailable() {
144 if (tracer_type_ != kTracerTypeInvalid) { 148 if (tracer_type_ != kTracerTypeInvalid) {
145 if (!end_requested_) 149 if (!end_requested_)
146 return false; 150 return false;
147 151
148 GLint done = 0; 152 GLint done = 0;
149 glGetQueryObjectiv(queries_[1], GL_QUERY_RESULT_AVAILABLE, &done); 153 glGetQueryObjectiv(queries_[1], GL_QUERY_RESULT_AVAILABLE, &done);
150 return !!done; 154 return !!done;
(...skipping 13 matching lines...) Expand all
164 168
165 // TODO(dsinclair): It's possible for the timer to wrap during the start/end. 169 // TODO(dsinclair): It's possible for the timer to wrap during the start/end.
166 // We need to detect if the end is less then the start and correct for the 170 // We need to detect if the end is less then the start and correct for the
167 // wrapping. 171 // wrapping.
168 glGetQueryObjectui64v(queries_[0], GL_QUERY_RESULT, &begin_stamp); 172 glGetQueryObjectui64v(queries_[0], GL_QUERY_RESULT, &begin_stamp);
169 glGetQueryObjectui64v(queries_[1], GL_QUERY_RESULT, &end_stamp); 173 glGetQueryObjectui64v(queries_[1], GL_QUERY_RESULT, &end_stamp);
170 174
171 start_time_ = (begin_stamp / base::Time::kNanosecondsPerMicrosecond) + 175 start_time_ = (begin_stamp / base::Time::kNanosecondsPerMicrosecond) +
172 offset_; 176 offset_;
173 end_time_ = (end_stamp / base::Time::kNanosecondsPerMicrosecond) + offset_; 177 end_time_ = (end_stamp / base::Time::kNanosecondsPerMicrosecond) + offset_;
174 outputter_->Trace(name(), start_time_, end_time_); 178 outputter_->Trace(category(), name(), start_time_, end_time_);
175 } 179 }
176 180
177 GPUTracer::GPUTracer(gles2::GLES2Decoder* decoder) 181 GPUTracer::GPUTracer(gles2::GLES2Decoder* decoder)
178 : gpu_trace_srv_category(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED( 182 : gpu_trace_srv_category(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(
179 TRACE_DISABLED_BY_DEFAULT("gpu.service"))), 183 TRACE_DISABLED_BY_DEFAULT("gpu.service"))),
180 gpu_trace_dev_category(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED( 184 gpu_trace_dev_category(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(
181 TRACE_DISABLED_BY_DEFAULT("gpu.device"))), 185 TRACE_DISABLED_BY_DEFAULT("gpu.device"))),
182 decoder_(decoder), 186 decoder_(decoder),
183 timer_offset_(0), 187 timer_offset_(0),
184 last_tracer_source_(kTraceGroupInvalid), 188 last_tracer_source_(kTraceGroupInvalid),
(...skipping 23 matching lines...) Expand all
208 if (IsTracing()) { 212 if (IsTracing()) {
209 // Reset disjoint bit for the disjoint timer. 213 // Reset disjoint bit for the disjoint timer.
210 if (tracer_type_ == kTracerTypeDisjointTimer) { 214 if (tracer_type_ == kTracerTypeDisjointTimer) {
211 GLint disjoint_value = 0; 215 GLint disjoint_value = 0;
212 glGetIntegerv(GL_GPU_DISJOINT_EXT, &disjoint_value); 216 glGetIntegerv(GL_GPU_DISJOINT_EXT, &disjoint_value);
213 } 217 }
214 218
215 // Begin a Trace for all active markers 219 // Begin a Trace for all active markers
216 for (int n = 0; n < NUM_TRACER_SOURCES; n++) { 220 for (int n = 0; n < NUM_TRACER_SOURCES; n++) {
217 for (size_t i = 0; i < markers_[n].size(); i++) { 221 for (size_t i = 0; i < markers_[n].size(); i++) {
218 markers_[n][i].trace_ = CreateTrace(markers_[n][i].name_); 222 TraceMarker& trace_marker = markers_[n][i];
219 markers_[n][i].trace_->Start(); 223 trace_marker.trace_ = CreateTrace(trace_marker.category_,
224 trace_marker.name_);
225 trace_marker.trace_->Start(*gpu_trace_srv_category != 0);
220 } 226 }
221 } 227 }
222 } 228 }
223 return true; 229 return true;
224 } 230 }
225 231
226 bool GPUTracer::EndDecoding() { 232 bool GPUTracer::EndDecoding() {
227 if (!gpu_executing_) 233 if (!gpu_executing_)
228 return false; 234 return false;
229 235
230 // End Trace for all active markers 236 // End Trace for all active markers
231 if (IsTracing()) { 237 if (IsTracing()) {
232 for (int n = 0; n < NUM_TRACER_SOURCES; n++) { 238 for (int n = 0; n < NUM_TRACER_SOURCES; n++) {
233 for (size_t i = 0; i < markers_[n].size(); i++) { 239 for (size_t i = 0; i < markers_[n].size(); i++) {
234 if (markers_[n][i].trace_.get()) { 240 if (markers_[n][i].trace_.get()) {
235 markers_[n][i].trace_->End(); 241 markers_[n][i].trace_->End(*gpu_trace_srv_category != 0);
236 if (markers_[n][i].trace_->IsEnabled()) 242 if (markers_[n][i].trace_->IsEnabled())
237 traces_.push_back(markers_[n][i].trace_); 243 traces_.push_back(markers_[n][i].trace_);
238 markers_[n][i].trace_ = 0; 244 markers_[n][i].trace_ = 0;
239 } 245 }
240 } 246 }
241 } 247 }
242 IssueProcessTask(); 248 IssueProcessTask();
243 } 249 }
244 250
245 gpu_executing_ = false; 251 gpu_executing_ = false;
246 252
247 // NOTE(vmiura): glFlush() here can help give better trace results, 253 // NOTE(vmiura): glFlush() here can help give better trace results,
248 // but it distorts the normal device behavior. 254 // but it distorts the normal device behavior.
249 return true; 255 return true;
250 } 256 }
251 257
252 bool GPUTracer::Begin(const std::string& name, GpuTracerSource source) { 258 bool GPUTracer::Begin(const std::string& category, const std::string& name,
259 GpuTracerSource source) {
253 if (!gpu_executing_) 260 if (!gpu_executing_)
254 return false; 261 return false;
255 262
256 DCHECK(source >= 0 && source < NUM_TRACER_SOURCES); 263 DCHECK(source >= 0 && source < NUM_TRACER_SOURCES);
257 264
258 // Push new marker from given 'source' 265 // Push new marker from given 'source'
259 last_tracer_source_ = source; 266 last_tracer_source_ = source;
260 markers_[source].push_back(TraceMarker(name)); 267 markers_[source].push_back(TraceMarker(category, name));
261 268
262 // Create trace 269 // Create trace
263 if (IsTracing()) { 270 if (IsTracing()) {
264 scoped_refptr<GPUTrace> trace = CreateTrace(name); 271 scoped_refptr<GPUTrace> trace = CreateTrace(category, name);
265 trace->Start(); 272 trace->Start(*gpu_trace_srv_category != 0);
266 markers_[source].back().trace_ = trace; 273 markers_[source].back().trace_ = trace;
267 } 274 }
268 275
269 return true; 276 return true;
270 } 277 }
271 278
272 bool GPUTracer::End(GpuTracerSource source) { 279 bool GPUTracer::End(GpuTracerSource source) {
273 if (!gpu_executing_) 280 if (!gpu_executing_)
274 return false; 281 return false;
275 282
276 DCHECK(source >= 0 && source < NUM_TRACER_SOURCES); 283 DCHECK(source >= 0 && source < NUM_TRACER_SOURCES);
277 284
278 // Pop last marker with matching 'source' 285 // Pop last marker with matching 'source'
279 if (!markers_[source].empty()) { 286 if (!markers_[source].empty()) {
280 if (IsTracing()) { 287 if (IsTracing()) {
281 scoped_refptr<GPUTrace> trace = markers_[source].back().trace_; 288 scoped_refptr<GPUTrace> trace = markers_[source].back().trace_;
282 if (trace.get()) { 289 if (trace.get()) {
283 trace->End(); 290 trace->End(*gpu_trace_srv_category != 0);
284 if (trace->IsEnabled()) 291 if (trace->IsEnabled())
285 traces_.push_back(trace); 292 traces_.push_back(trace);
286 IssueProcessTask(); 293 IssueProcessTask();
287 } 294 }
288 } 295 }
289 296
290 markers_[source].pop_back(); 297 markers_[source].pop_back();
291 return true; 298 return true;
292 } 299 }
293 return false; 300 return false;
294 } 301 }
295 302
296 bool GPUTracer::IsTracing() { 303 bool GPUTracer::IsTracing() {
297 return (*gpu_trace_srv_category != 0) || (*gpu_trace_dev_category != 0); 304 return (*gpu_trace_srv_category != 0) || (*gpu_trace_dev_category != 0);
298 } 305 }
299 306
307 const std::string& GPUTracer::CurrentCategory() const {
308 if (last_tracer_source_ >= 0 &&
309 last_tracer_source_ < NUM_TRACER_SOURCES &&
310 !markers_[last_tracer_source_].empty()) {
311 return markers_[last_tracer_source_].back().category_;
312 }
313 return base::EmptyString();
314 }
315
300 const std::string& GPUTracer::CurrentName() const { 316 const std::string& GPUTracer::CurrentName() const {
301 if (last_tracer_source_ >= 0 && 317 if (last_tracer_source_ >= 0 &&
302 last_tracer_source_ < NUM_TRACER_SOURCES && 318 last_tracer_source_ < NUM_TRACER_SOURCES &&
303 !markers_[last_tracer_source_].empty()) { 319 !markers_[last_tracer_source_].empty()) {
304 return markers_[last_tracer_source_].back().name_; 320 return markers_[last_tracer_source_].back().name_;
305 } 321 }
306 return base::EmptyString(); 322 return base::EmptyString();
307 } 323 }
308 324
309 scoped_refptr<GPUTrace> GPUTracer::CreateTrace(const std::string& name) { 325 scoped_refptr<GPUTrace> GPUTracer::CreateTrace(const std::string& category,
326 const std::string& name) {
310 GpuTracerType tracer_type = *gpu_trace_dev_category ? tracer_type_ : 327 GpuTracerType tracer_type = *gpu_trace_dev_category ? tracer_type_ :
311 kTracerTypeInvalid; 328 kTracerTypeInvalid;
312 329
313 return new GPUTrace(outputter_, name, timer_offset_, tracer_type); 330 return new GPUTrace(outputter_, category, name, timer_offset_, tracer_type);
314 } 331 }
315 332
316 void GPUTracer::Process() { 333 void GPUTracer::Process() {
317 process_posted_ = false; 334 process_posted_ = false;
318 ProcessTraces(); 335 ProcessTraces();
319 IssueProcessTask(); 336 IssueProcessTask();
320 } 337 }
321 338
322 void GPUTracer::ProcessTraces() { 339 void GPUTracer::ProcessTraces() {
323 if (tracer_type_ == kTracerTypeInvalid) { 340 if (tracer_type_ == kTracerTypeInvalid) {
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
398 415
399 process_posted_ = true; 416 process_posted_ = true;
400 base::MessageLoop::current()->PostDelayedTask( 417 base::MessageLoop::current()->PostDelayedTask(
401 FROM_HERE, 418 FROM_HERE,
402 base::Bind(&GPUTracer::Process, base::AsWeakPtr(this)), 419 base::Bind(&GPUTracer::Process, base::AsWeakPtr(this)),
403 base::TimeDelta::FromMilliseconds(kProcessInterval)); 420 base::TimeDelta::FromMilliseconds(kProcessInterval));
404 } 421 }
405 422
406 } // namespace gles2 423 } // namespace gles2
407 } // namespace gpu 424 } // namespace gpu
OLDNEW
« no previous file with comments | « gpu/command_buffer/service/gpu_tracer.h ('k') | gpu/command_buffer/service/gpu_tracer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698