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