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

Unified Diff: gpu/command_buffer/service/gpu_tracer.cc

Issue 509723002: Added support for GPU Tracing on mobile devices which support it. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed another gpu tracer unittest issue Created 6 years, 3 months 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 side-by-side diff with in-line comments
Download patch
« 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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: gpu/command_buffer/service/gpu_tracer.cc
diff --git a/gpu/command_buffer/service/gpu_tracer.cc b/gpu/command_buffer/service/gpu_tracer.cc
index b1c9f23e4858f5a68ac1c1e3b161c956c02d56ee..9bcb36aed4fa024940bfaec6f4db90dfb1201020 100644
--- a/gpu/command_buffer/service/gpu_tracer.cc
+++ b/gpu/command_buffer/service/gpu_tracer.cc
@@ -59,45 +59,70 @@ void TraceOutputter::Trace(const std::string& name,
++local_trace_id_;
}
-GPUTrace::GPUTrace(const std::string& name)
- : name_(name),
- outputter_(NULL),
- offset_(0),
- end_time_(0),
- end_requested_(false),
- enabled_(false) {
-}
-
GPUTrace::GPUTrace(scoped_refptr<Outputter> outputter,
const std::string& name,
- int64 offset)
+ int64 offset,
+ GpuTracerType tracer_type)
: name_(name),
outputter_(outputter),
offset_(offset),
start_time_(0),
end_time_(0),
- end_requested_(false),
- enabled_(true) {
- glGenQueries(2, queries_);
+ tracer_type_(tracer_type),
+ end_requested_(false) {
+ memset(queries_, 0, sizeof(queries_));
+ switch (tracer_type_) {
+ case kTracerTypeARBTimer:
+ case kTracerTypeDisjointTimer:
+ glGenQueriesARB(2, queries_);
+ break;
+
+ default:
+ tracer_type_ = kTracerTypeInvalid;
+ }
}
GPUTrace::~GPUTrace() {
- if (enabled_)
- glDeleteQueries(2, queries_);
+ switch (tracer_type_) {
+ case kTracerTypeInvalid:
+ break;
+
+ case kTracerTypeARBTimer:
+ case kTracerTypeDisjointTimer:
+ glDeleteQueriesARB(2, queries_);
+ break;
+ }
}
void GPUTrace::Start() {
TRACE_EVENT_COPY_ASYNC_BEGIN0(
TRACE_DISABLED_BY_DEFAULT("gpu.service"), name().c_str(), this);
- if (enabled_) {
- glQueryCounter(queries_[0], GL_TIMESTAMP);
+
+ switch (tracer_type_) {
+ case kTracerTypeInvalid:
+ break;
+
+ case kTracerTypeARBTimer:
+ glQueryCounter(queries_[0], GL_TIMESTAMP);
+ break;
+ case kTracerTypeDisjointTimer:
+ glQueryCounter(queries_[0], GL_TIMESTAMP_EXT);
piman 2014/09/02 18:41:44 nit: GL_TIMESTAMP_EXT and GL_TIMESTAMP have the sa
David Yen 2014/09/02 18:45:36 I noticed that as well, but I wanted to follow the
David Yen 2014/09/02 22:03:55 Done.
+ break;
}
}
void GPUTrace::End() {
- if (enabled_) {
- glQueryCounter(queries_[1], GL_TIMESTAMP);
- end_requested_ = true;
+ end_requested_ = true;
+ switch (tracer_type_) {
+ case kTracerTypeInvalid:
+ break;
+
+ case kTracerTypeARBTimer:
+ glQueryCounter(queries_[1], GL_TIMESTAMP);
+ break;
+ case kTracerTypeDisjointTimer:
+ glQueryCounter(queries_[1], GL_TIMESTAMP_EXT);
piman 2014/09/02 18:41:44 nit: same here
David Yen 2014/09/02 22:03:55 Done.
+ break;
}
TRACE_EVENT_COPY_ASYNC_END0(
@@ -105,34 +130,62 @@ void GPUTrace::End() {
}
bool GPUTrace::IsAvailable() {
- if (!enabled_)
- return true;
- else if (!end_requested_)
- return false;
+ if (tracer_type_ != kTracerTypeInvalid) {
+ if (!end_requested_)
+ return false;
+
+ GLint done = 0;
+
+ switch (tracer_type_) {
+ case kTracerTypeARBTimer:
+ glGetQueryObjectiv(queries_[1], GL_QUERY_RESULT_AVAILABLE, &done);
+ break;
- GLint done = 0;
- glGetQueryObjectiv(queries_[1], GL_QUERY_RESULT_AVAILABLE, &done);
- return !!done;
+ case kTracerTypeDisjointTimer:
+ glGetQueryObjectivARB(queries_[1], GL_QUERY_RESULT_AVAILABLE_EXT,
+ &done);
piman 2014/09/02 18:41:44 Same here with GL_QUERY_RESULT_AVAILABLE_EXT vs GL
David Yen 2014/09/02 22:03:55 Done.
+ break;
+
+ default:
+ done = 1;
+ break;
+ }
+
+ return !!done;
+ }
+
+ return true;
}
void GPUTrace::Process() {
- if (!enabled_)
+ if (tracer_type_ == kTracerTypeInvalid)
return;
DCHECK(IsAvailable());
- GLuint64 timestamp;
+ GLuint64 begin_stamp = 0;
+ GLuint64 end_stamp = 0;
// TODO(dsinclair): It's possible for the timer to wrap during the start/end.
// We need to detect if the end is less then the start and correct for the
// wrapping.
- glGetQueryObjectui64v(queries_[0], GL_QUERY_RESULT, &timestamp);
- start_time_ = (timestamp / base::Time::kNanosecondsPerMicrosecond) + offset_;
-
- glGetQueryObjectui64v(queries_[1], GL_QUERY_RESULT, &timestamp);
- end_time_ = (timestamp / base::Time::kNanosecondsPerMicrosecond) + offset_;
+ switch (tracer_type_) {
+ case kTracerTypeARBTimer:
+ glGetQueryObjectui64v(queries_[0], GL_QUERY_RESULT, &begin_stamp);
+ glGetQueryObjectui64v(queries_[1], GL_QUERY_RESULT, &end_stamp);
+ break;
+ case kTracerTypeDisjointTimer:
+ glGetQueryObjectui64vEXT(queries_[0], GL_QUERY_RESULT_EXT, &begin_stamp);
+ glGetQueryObjectui64vEXT(queries_[1], GL_QUERY_RESULT_EXT, &end_stamp);
piman 2014/09/02 18:41:44 nit: can we collapse those as well?
David Yen 2014/09/02 18:45:36 When I collapsed these, it actually started to cra
David Yen 2014/09/02 22:03:55 Re-did this and the crashing no longer happens, mu
+ break;
+
+ default:
+ return;
+ }
- glDeleteQueries(2, queries_);
+ start_time_ = (begin_stamp / base::Time::kNanosecondsPerMicrosecond) +
+ offset_;
+ end_time_ = (end_stamp / base::Time::kNanosecondsPerMicrosecond) + offset_;
outputter_->Trace(name(), start_time_, end_time_);
}
@@ -144,13 +197,16 @@ GPUTracer::GPUTracer(gles2::GLES2Decoder* decoder)
decoder_(decoder),
timer_offset_(0),
last_tracer_source_(kTraceGroupInvalid),
- enabled_(false),
+ tracer_type_(kTracerTypeInvalid),
gpu_timing_synced_(false),
gpu_executing_(false),
process_posted_(false) {
- if (gfx::g_driver_gl.ext.b_GL_ARB_timer_query) {
+ if (gfx::g_driver_gl.ext.b_GL_EXT_disjoint_timer_query) {
+ tracer_type_ = kTracerTypeDisjointTimer;
+ outputter_ = TraceOutputter::Create("GL_EXT_disjoint_timer_query");
+ } else if (gfx::g_driver_gl.ext.b_GL_ARB_timer_query) {
+ tracer_type_ = kTracerTypeARBTimer;
outputter_ = TraceOutputter::Create("GL_ARB_timer_query");
- enabled_ = true;
}
}
@@ -158,25 +214,19 @@ GPUTracer::~GPUTracer() {
}
bool GPUTracer::BeginDecoding() {
- if (enabled_) {
- if (*gpu_trace_dev_category) {
- // Make sure timing is synced before tracing
- if (!gpu_timing_synced_) {
- CalculateTimerOffset();
- gpu_timing_synced_ = true;
- }
- } else {
- // If GPU device category is off, invalidate timing sync
- gpu_timing_synced_ = false;
- }
- }
-
if (gpu_executing_)
return false;
+ CalculateTimerOffset();
gpu_executing_ = true;
if (IsTracing()) {
+ // Reset disjoint bit for the disjoint timer.
+ if (tracer_type_ == kTracerTypeDisjointTimer) {
+ GLint disjoint_value = 0;
+ glGetIntegerv(GL_GPU_DISJOINT_EXT, &disjoint_value);
+ }
+
// Begin a Trace for all active markers
for (int n = 0; n < NUM_TRACER_SOURCES; n++) {
for (size_t i = 0; i < markers_[n].size(); i++) {
@@ -272,10 +322,10 @@ const std::string& GPUTracer::CurrentName() const {
}
scoped_refptr<GPUTrace> GPUTracer::CreateTrace(const std::string& name) {
- if (enabled_ && *gpu_trace_dev_category)
- return new GPUTrace(outputter_, name, timer_offset_);
- else
- return new GPUTrace(name);
+ GpuTracerType tracer_type = *gpu_trace_dev_category ? tracer_type_ :
+ kTracerTypeInvalid;
+
+ return new GPUTrace(outputter_, name, timer_offset_, tracer_type);
}
void GPUTracer::Process() {
@@ -285,11 +335,8 @@ void GPUTracer::Process() {
}
void GPUTracer::ProcessTraces() {
- if (!enabled_) {
- while (!traces_.empty() && traces_.front()->IsAvailable()) {
- traces_.front()->Process();
- traces_.pop_front();
- }
+ if (tracer_type_ == kTracerTypeInvalid) {
+ traces_.clear();
return;
}
@@ -302,6 +349,14 @@ void GPUTracer::ProcessTraces() {
return;
}
+ // Check if disjoint operation has occurred, discard ongoing traces if so.
+ if (tracer_type_ == kTracerTypeDisjointTimer) {
+ GLint disjoint_value = 0;
+ glGetIntegerv(GL_GPU_DISJOINT_EXT, &disjoint_value);
+ if (disjoint_value)
+ traces_.clear();
+ }
+
while (!traces_.empty() && traces_.front()->IsAvailable()) {
traces_.front()->Process();
traces_.pop_front();
@@ -314,23 +369,63 @@ void GPUTracer::ProcessTraces() {
}
void GPUTracer::CalculateTimerOffset() {
- if (enabled_) {
+ if (tracer_type_ != kTracerTypeInvalid) {
+ // If GPU device category is off, invalidate timing sync.
+ if (*gpu_trace_dev_category == '\0') {
+ gpu_timing_synced_ = false;
+ return;
+ }
+
+ if (gpu_timing_synced_)
+ return;
+
TRACE_EVENT0("gpu", "GPUTracer::CalculateTimerOffset");
// NOTE(vmiura): It would be better to use glGetInteger64v, however
// it's not available everywhere.
GLuint64 gl_now = 0;
GLuint query;
- glFinish();
- glGenQueries(1, &query);
- glQueryCounter(query, GL_TIMESTAMP);
- glFinish();
- glGetQueryObjectui64v(query, GL_QUERY_RESULT, &gl_now);
+ GLint disjoint_value = 0;
+
+ switch (tracer_type_) {
+ case kTracerTypeARBTimer:
+ glFinish();
+ glGenQueriesARB(1, &query);
+ glQueryCounter(query, GL_TIMESTAMP);
+ glFinish();
+
+ glGetQueryObjectui64v(query, GL_QUERY_RESULT, &gl_now);
+ glDeleteQueriesARB(1, &query);
+ break;
+
+ case kTracerTypeDisjointTimer:
+ // Clear the disjoint bit before we do any queries.
+ glGetIntegerv(GL_GPU_DISJOINT_EXT, &disjoint_value);
+
+ glFinish();
+ glGenQueriesARB(1, &query);
+ glQueryCounter(query, GL_TIMESTAMP_EXT);
+ glFinish();
+
+ glGetQueryObjectui64vEXT(query, GL_QUERY_RESULT_EXT, &gl_now);
+ glDeleteQueriesARB(1, &query);
+
+ // Discard results if disjoint operation has occurred.
+ glGetIntegerv(GL_GPU_DISJOINT_EXT, &disjoint_value);
+ if (disjoint_value)
+ return;
+
+ break;
+
+ default:
+ break;
+ }
+
base::TimeTicks system_now = base::TimeTicks::NowFromSystemTraceTime();
gl_now /= base::Time::kNanosecondsPerMicrosecond;
timer_offset_ = system_now.ToInternalValue() - gl_now;
- glDeleteQueries(1, &query);
+ gpu_timing_synced_ = true;
}
}
« 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