| 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/debug/trace_event.h" | 10 #include "base/debug/trace_event.h" |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 95 } | 95 } |
| 96 | 96 |
| 97 void GPUTrace::Start() { | 97 void GPUTrace::Start() { |
| 98 TRACE_EVENT_COPY_ASYNC_BEGIN0( | 98 TRACE_EVENT_COPY_ASYNC_BEGIN0( |
| 99 TRACE_DISABLED_BY_DEFAULT("gpu.service"), name().c_str(), this); | 99 TRACE_DISABLED_BY_DEFAULT("gpu.service"), name().c_str(), this); |
| 100 | 100 |
| 101 switch (tracer_type_) { | 101 switch (tracer_type_) { |
| 102 case kTracerTypeInvalid: | 102 case kTracerTypeInvalid: |
| 103 break; | 103 break; |
| 104 | 104 |
| 105 case kTracerTypeDisjointTimer: |
| 106 // 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 |
| 108 // good news is any device that supports disjoint timer will also support |
| 109 // glGetInteger64v, so we can query it directly unlike the ARBTimer case. |
| 110 // 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. |
| 112 if (offset_ == 0) { |
| 113 GLint64 gl_now = 0; |
| 114 glGetInteger64v(GL_TIMESTAMP, &gl_now); |
| 115 offset_ = base::TimeTicks::NowFromSystemTraceTime().ToInternalValue() - |
| 116 gl_now / base::Time::kNanosecondsPerMicrosecond; |
| 117 } |
| 118 // Intentionally fall through to kTracerTypeARBTimer case.xs |
| 105 case kTracerTypeARBTimer: | 119 case kTracerTypeARBTimer: |
| 106 case kTracerTypeDisjointTimer: | |
| 107 // GL_TIMESTAMP and GL_TIMESTAMP_EXT both have the same value. | 120 // GL_TIMESTAMP and GL_TIMESTAMP_EXT both have the same value. |
| 108 glQueryCounter(queries_[0], GL_TIMESTAMP); | 121 glQueryCounter(queries_[0], GL_TIMESTAMP); |
| 109 break; | 122 break; |
| 110 } | 123 } |
| 111 } | 124 } |
| 112 | 125 |
| 113 void GPUTrace::End() { | 126 void GPUTrace::End() { |
| 114 end_requested_ = true; | 127 end_requested_ = true; |
| 115 switch (tracer_type_) { | 128 switch (tracer_type_) { |
| 116 case kTracerTypeInvalid: | 129 case kTracerTypeInvalid: |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 335 } | 348 } |
| 336 | 349 |
| 337 // Clear pending traces if there were are any errors | 350 // Clear pending traces if there were are any errors |
| 338 GLenum err = glGetError(); | 351 GLenum err = glGetError(); |
| 339 if (err != GL_NO_ERROR) | 352 if (err != GL_NO_ERROR) |
| 340 traces_.clear(); | 353 traces_.clear(); |
| 341 } | 354 } |
| 342 | 355 |
| 343 void GPUTracer::CalculateTimerOffset() { | 356 void GPUTracer::CalculateTimerOffset() { |
| 344 if (tracer_type_ != kTracerTypeInvalid) { | 357 if (tracer_type_ != kTracerTypeInvalid) { |
| 345 // If GPU device category is off, invalidate timing sync. | |
| 346 if (*gpu_trace_dev_category == '\0') { | 358 if (*gpu_trace_dev_category == '\0') { |
| 359 // If GPU device category is off, invalidate timing sync. |
| 347 gpu_timing_synced_ = false; | 360 gpu_timing_synced_ = false; |
| 348 return; | 361 return; |
| 362 } else if (tracer_type_ == kTracerTypeDisjointTimer) { |
| 363 // Disjoint timers offsets should be calculated before every query. |
| 364 gpu_timing_synced_ = true; |
| 365 timer_offset_ = 0; |
| 349 } | 366 } |
| 350 | 367 |
| 351 if (gpu_timing_synced_) | 368 if (gpu_timing_synced_) |
| 352 return; | 369 return; |
| 353 | 370 |
| 354 TRACE_EVENT0("gpu", "GPUTracer::CalculateTimerOffset"); | 371 TRACE_EVENT0("gpu", "GPUTracer::CalculateTimerOffset"); |
| 355 | 372 |
| 356 // NOTE(vmiura): It would be better to use glGetInteger64v, however | 373 // NOTE(vmiura): It would be better to use glGetInteger64v, however |
| 357 // it's not available everywhere. | 374 // it's not available everywhere. |
| 358 GLuint64 gl_now = 0; | 375 GLuint64 gl_now = 0; |
| 359 GLuint query; | 376 GLuint query; |
| 360 GLint disjoint_value = 0; | |
| 361 | 377 |
| 362 if (tracer_type_ == kTracerTypeDisjointTimer) { | 378 glGenQueriesARB(1, &query); |
| 363 // Clear the disjoint bit before we do any queries. | |
| 364 glGetIntegerv(GL_GPU_DISJOINT_EXT, &disjoint_value); | |
| 365 } | |
| 366 | 379 |
| 367 glFinish(); | 380 glFinish(); |
| 368 glGenQueriesARB(1, &query); | |
| 369 glQueryCounter(query, GL_TIMESTAMP); | 381 glQueryCounter(query, GL_TIMESTAMP); |
| 370 glFinish(); | 382 glFinish(); |
| 371 | 383 |
| 372 glGetQueryObjectui64v(query, GL_QUERY_RESULT, &gl_now); | 384 glGetQueryObjectui64v(query, GL_QUERY_RESULT, &gl_now); |
| 373 glDeleteQueriesARB(1, &query); | 385 glDeleteQueriesARB(1, &query); |
| 374 | 386 |
| 375 if (tracer_type_ == kTracerTypeDisjointTimer) { | |
| 376 glGetIntegerv(GL_GPU_DISJOINT_EXT, &disjoint_value); | |
| 377 if (disjoint_value) | |
| 378 return; | |
| 379 } | |
| 380 | |
| 381 base::TimeTicks system_now = base::TimeTicks::NowFromSystemTraceTime(); | 387 base::TimeTicks system_now = base::TimeTicks::NowFromSystemTraceTime(); |
| 382 | 388 |
| 383 gl_now /= base::Time::kNanosecondsPerMicrosecond; | 389 gl_now /= base::Time::kNanosecondsPerMicrosecond; |
| 384 timer_offset_ = system_now.ToInternalValue() - gl_now; | 390 timer_offset_ = system_now.ToInternalValue() - gl_now; |
| 385 gpu_timing_synced_ = true; | 391 gpu_timing_synced_ = true; |
| 386 } | 392 } |
| 387 } | 393 } |
| 388 | 394 |
| 389 void GPUTracer::IssueProcessTask() { | 395 void GPUTracer::IssueProcessTask() { |
| 390 if (traces_.empty() || process_posted_) | 396 if (traces_.empty() || process_posted_) |
| 391 return; | 397 return; |
| 392 | 398 |
| 393 process_posted_ = true; | 399 process_posted_ = true; |
| 394 base::MessageLoop::current()->PostDelayedTask( | 400 base::MessageLoop::current()->PostDelayedTask( |
| 395 FROM_HERE, | 401 FROM_HERE, |
| 396 base::Bind(&GPUTracer::Process, base::AsWeakPtr(this)), | 402 base::Bind(&GPUTracer::Process, base::AsWeakPtr(this)), |
| 397 base::TimeDelta::FromMilliseconds(kProcessInterval)); | 403 base::TimeDelta::FromMilliseconds(kProcessInterval)); |
| 398 } | 404 } |
| 399 | 405 |
| 400 } // namespace gles2 | 406 } // namespace gles2 |
| 401 } // namespace gpu | 407 } // namespace gpu |
| OLD | NEW |