| 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 |