OLD | NEW |
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/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 enabled_(enabled) { | 92 enabled_(enabled) { |
93 if (gpu_timing_client->IsAvailable() && | 93 if (gpu_timing_client->IsAvailable() && |
94 gpu_timing_client->IsTimerOffsetAvailable()) { | 94 gpu_timing_client->IsTimerOffsetAvailable()) { |
95 gpu_timer_ = gpu_timing_client->CreateGPUTimer(); | 95 gpu_timer_ = gpu_timing_client->CreateGPUTimer(); |
96 } | 96 } |
97 } | 97 } |
98 | 98 |
99 GPUTrace::~GPUTrace() { | 99 GPUTrace::~GPUTrace() { |
100 } | 100 } |
101 | 101 |
| 102 void GPUTrace::Destroy(bool have_context) { |
| 103 if (gpu_timer_.get()) { |
| 104 gpu_timer_->Destroy(have_context); |
| 105 } |
| 106 } |
| 107 |
102 void GPUTrace::Start(bool trace_service) { | 108 void GPUTrace::Start(bool trace_service) { |
103 if (trace_service) { | 109 if (trace_service) { |
104 outputter_->TraceServiceBegin(category_, name_); | 110 outputter_->TraceServiceBegin(category_, name_); |
105 } | 111 } |
106 if (gpu_timer_.get()) { | 112 if (gpu_timer_.get()) { |
107 gpu_timer_->Start(); | 113 gpu_timer_->Start(); |
108 } | 114 } |
109 } | 115 } |
110 | 116 |
111 void GPUTrace::End(bool tracing_service) { | 117 void GPUTrace::End(bool tracing_service) { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 if (context) { | 151 if (context) { |
146 gpu_timing_client_ = context->CreateGPUTimingClient(); | 152 gpu_timing_client_ = context->CreateGPUTimingClient(); |
147 } else { | 153 } else { |
148 gpu_timing_client_ = new gfx::GPUTimingClient(); | 154 gpu_timing_client_ = new gfx::GPUTimingClient(); |
149 } | 155 } |
150 } | 156 } |
151 | 157 |
152 GPUTracer::~GPUTracer() { | 158 GPUTracer::~GPUTracer() { |
153 } | 159 } |
154 | 160 |
| 161 void GPUTracer::Destroy(bool have_context) { |
| 162 for (int n = 0; n < NUM_TRACER_SOURCES; n++) { |
| 163 for (size_t i = 0; i < markers_[n].size(); i++) { |
| 164 TraceMarker& marker = markers_[n][i]; |
| 165 if (marker.trace_.get()) { |
| 166 marker.trace_->Destroy(have_context); |
| 167 marker.trace_ = 0; |
| 168 } |
| 169 } |
| 170 } |
| 171 |
| 172 ClearFinishedTraces(have_context); |
| 173 } |
| 174 |
155 bool GPUTracer::BeginDecoding() { | 175 bool GPUTracer::BeginDecoding() { |
156 if (gpu_executing_) | 176 if (gpu_executing_) |
157 return false; | 177 return false; |
158 | 178 |
159 if (!outputter_) { | 179 if (!outputter_) { |
160 outputter_ = CreateOutputter(gpu_timing_client_->GetTimerTypeName()); | 180 outputter_ = CreateOutputter(gpu_timing_client_->GetTimerTypeName()); |
161 } | 181 } |
162 | 182 |
163 if (*gpu_trace_dev_category == '\0') { | 183 if (*gpu_trace_dev_category == '\0') { |
164 // If GPU device category is off, invalidate timing sync. | 184 // If GPU device category is off, invalidate timing sync. |
(...skipping 22 matching lines...) Expand all Loading... |
187 if (!gpu_executing_) | 207 if (!gpu_executing_) |
188 return false; | 208 return false; |
189 | 209 |
190 // End Trace for all active markers | 210 // End Trace for all active markers |
191 if (IsTracing()) { | 211 if (IsTracing()) { |
192 for (int n = 0; n < NUM_TRACER_SOURCES; n++) { | 212 for (int n = 0; n < NUM_TRACER_SOURCES; n++) { |
193 for (size_t i = 0; i < markers_[n].size(); i++) { | 213 for (size_t i = 0; i < markers_[n].size(); i++) { |
194 TraceMarker& marker = markers_[n][i]; | 214 TraceMarker& marker = markers_[n][i]; |
195 if (marker.trace_.get()) { | 215 if (marker.trace_.get()) { |
196 marker.trace_->End(*gpu_trace_srv_category != 0); | 216 marker.trace_->End(*gpu_trace_srv_category != 0); |
197 if (marker.trace_->IsEnabled()) | |
198 traces_.push_back(marker.trace_); | |
199 | 217 |
200 markers_[n][i].trace_ = 0; | 218 finished_traces_.push_back(marker.trace_); |
| 219 marker.trace_ = 0; |
201 } | 220 } |
202 } | 221 } |
203 } | 222 } |
204 IssueProcessTask(); | 223 IssueProcessTask(); |
205 } | 224 } |
206 | 225 |
207 gpu_executing_ = false; | 226 gpu_executing_ = false; |
208 | 227 |
209 // NOTE(vmiura): glFlush() here can help give better trace results, | 228 // NOTE(vmiura): glFlush() here can help give better trace results, |
210 // but it distorts the normal device behavior. | 229 // but it distorts the normal device behavior. |
(...skipping 23 matching lines...) Expand all Loading... |
234 } | 253 } |
235 | 254 |
236 bool GPUTracer::End(GpuTracerSource source) { | 255 bool GPUTracer::End(GpuTracerSource source) { |
237 if (!gpu_executing_) | 256 if (!gpu_executing_) |
238 return false; | 257 return false; |
239 | 258 |
240 DCHECK(source >= 0 && source < NUM_TRACER_SOURCES); | 259 DCHECK(source >= 0 && source < NUM_TRACER_SOURCES); |
241 | 260 |
242 // Pop last marker with matching 'source' | 261 // Pop last marker with matching 'source' |
243 if (!markers_[source].empty()) { | 262 if (!markers_[source].empty()) { |
244 if (IsTracing()) { | 263 scoped_refptr<GPUTrace> trace = markers_[source].back().trace_; |
245 scoped_refptr<GPUTrace> trace = markers_[source].back().trace_; | 264 if (trace.get()) { |
246 if (trace.get()) { | 265 if (IsTracing()) { |
247 trace->End(*gpu_trace_srv_category != 0); | 266 trace->End(*gpu_trace_srv_category != 0); |
248 if (trace->IsEnabled()) | |
249 traces_.push_back(trace); | |
250 IssueProcessTask(); | |
251 } | 267 } |
| 268 |
| 269 finished_traces_.push_back(trace); |
| 270 IssueProcessTask(); |
252 } | 271 } |
253 | 272 |
254 markers_[source].pop_back(); | 273 markers_[source].pop_back(); |
255 return true; | 274 return true; |
256 } | 275 } |
257 return false; | 276 return false; |
258 } | 277 } |
259 | 278 |
260 bool GPUTracer::IsTracing() { | 279 bool GPUTracer::IsTracing() { |
261 return (*gpu_trace_srv_category != 0) || (*gpu_trace_dev_category != 0); | 280 return (*gpu_trace_srv_category != 0) || (*gpu_trace_dev_category != 0); |
(...skipping 29 matching lines...) Expand all Loading... |
291 } | 310 } |
292 | 311 |
293 void GPUTracer::Process() { | 312 void GPUTracer::Process() { |
294 process_posted_ = false; | 313 process_posted_ = false; |
295 ProcessTraces(); | 314 ProcessTraces(); |
296 IssueProcessTask(); | 315 IssueProcessTask(); |
297 } | 316 } |
298 | 317 |
299 void GPUTracer::ProcessTraces() { | 318 void GPUTracer::ProcessTraces() { |
300 if (!gpu_timing_client_->IsAvailable()) { | 319 if (!gpu_timing_client_->IsAvailable()) { |
301 traces_.clear(); | 320 ClearFinishedTraces(false); |
302 return; | 321 return; |
303 } | 322 } |
304 | 323 |
305 TRACE_EVENT0("gpu", "GPUTracer::ProcessTraces"); | 324 TRACE_EVENT0("gpu", "GPUTracer::ProcessTraces"); |
306 | 325 |
307 // Make owning decoder's GL context current | 326 // Make owning decoder's GL context current |
308 if (!decoder_->MakeCurrent()) { | 327 if (!decoder_->MakeCurrent()) { |
309 // Skip subsequent GL calls if MakeCurrent fails | 328 // Skip subsequent GL calls if MakeCurrent fails |
310 traces_.clear(); | 329 ClearFinishedTraces(false); |
311 return; | 330 return; |
312 } | 331 } |
313 | 332 |
314 // Check if timers are still valid (e.g: a disjoint operation | 333 // Check if timers are still valid (e.g: a disjoint operation |
315 // might have occurred.) | 334 // might have occurred.) |
316 if (gpu_timing_client_->CheckAndResetTimerErrors()) | 335 if (gpu_timing_client_->CheckAndResetTimerErrors()) { |
317 traces_.clear(); | 336 ClearFinishedTraces(true); |
| 337 } |
318 | 338 |
319 while (!traces_.empty() && traces_.front()->IsAvailable()) { | 339 while (!finished_traces_.empty()) { |
320 traces_.front()->Process(); | 340 scoped_refptr<GPUTrace>& trace = finished_traces_.front(); |
321 traces_.pop_front(); | 341 if (trace->IsEnabled()) { |
| 342 if (!finished_traces_.front()->IsAvailable()) |
| 343 break; |
| 344 finished_traces_.front()->Process(); |
| 345 } |
| 346 finished_traces_.front()->Destroy(true); |
| 347 finished_traces_.pop_front(); |
322 } | 348 } |
323 | 349 |
324 // Clear pending traces if there were are any errors | 350 // Clear pending traces if there were are any errors |
325 GLenum err = glGetError(); | 351 GLenum err = glGetError(); |
326 if (err != GL_NO_ERROR) | 352 if (err != GL_NO_ERROR) |
327 traces_.clear(); | 353 ClearFinishedTraces(true); |
| 354 } |
| 355 |
| 356 void GPUTracer::ClearFinishedTraces(bool have_context) { |
| 357 while (!finished_traces_.empty()) { |
| 358 finished_traces_.front()->Destroy(have_context); |
| 359 finished_traces_.pop_front(); |
| 360 } |
328 } | 361 } |
329 | 362 |
330 void GPUTracer::IssueProcessTask() { | 363 void GPUTracer::IssueProcessTask() { |
331 if (traces_.empty() || process_posted_) | 364 if (finished_traces_.empty() || process_posted_) |
332 return; | 365 return; |
333 | 366 |
334 process_posted_ = true; | 367 process_posted_ = true; |
335 PostTask(); | 368 PostTask(); |
336 } | 369 } |
337 | 370 |
338 } // namespace gles2 | 371 } // namespace gles2 |
339 } // namespace gpu | 372 } // namespace gpu |
OLD | NEW |