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

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 unit test Created 6 years, 4 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
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..bd9bde0db41926eaaa60ca2f74ae21904d426c31 100644
--- a/gpu/command_buffer/service/gpu_tracer.cc
+++ b/gpu/command_buffer/service/gpu_tracer.cc
@@ -59,45 +59,75 @@ 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),
+ tracer_type_(tracer_type),
end_requested_(false),
- enabled_(true) {
- glGenQueries(2, queries_);
+ discard_trace_(false) {
+ memset(queries_, 0, sizeof(queries_));
+ switch (tracer_type_) {
+ case kTracerTypeARBTimer:
+ glGenQueries(2, queries_);
+ break;
+ case kTracerTypeDisjointTimer:
+ glGenQueriesEXT(2, queries_);
+ break;
+
+ default:
+ tracer_type_ = kTracerTypeInvalid;
+ }
}
GPUTrace::~GPUTrace() {
- if (enabled_)
- glDeleteQueries(2, queries_);
+ switch (tracer_type_) {
+ case kTracerTypeInvalid:
+ break;
+
+ case kTracerTypeARBTimer:
+ glDeleteQueries(2, queries_);
+ break;
+ case kTracerTypeDisjointTimer:
+ glDeleteQueriesEXT(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:
+ glQueryCounterEXT(queries_[0], GL_TIMESTAMP_EXT);
+ 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:
+ glQueryCounterEXT(queries_[1], GL_TIMESTAMP_EXT);
+ break;
}
TRACE_EVENT_COPY_ASYNC_END0(
@@ -105,37 +135,75 @@ 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;
+ else if (discard_trace_)
+ return true;
+
+ GLint done = 0;
+
+ switch (tracer_type_) {
+ case kTracerTypeARBTimer:
+ glGetQueryObjectiv(queries_[1], GL_QUERY_RESULT_AVAILABLE, &done);
+ break;
+
+ case kTracerTypeDisjointTimer:
+ glGetQueryObjectivEXT(queries_[1], GL_QUERY_RESULT_AVAILABLE_EXT,
+ &done);
+ break;
+
+ default:
+ done = 1;
+ break;
+ }
+
+ return !!done;
+ }
- GLint done = 0;
- glGetQueryObjectiv(queries_[1], GL_QUERY_RESULT_AVAILABLE, &done);
- return !!done;
+ return true;
}
void GPUTrace::Process() {
- if (!enabled_)
+ if (tracer_type_ == kTracerTypeInvalid)
return;
DCHECK(IsAvailable());
- GLuint64 timestamp;
+ GLuint64 beg_stamp = 0;
piman 2014/08/26 23:43:57 nit: no abbreviations. begin_stamp?
David Yen 2014/08/27 17:03:13 This was shortened to avoid multiple lines for som
+ 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_;
+ switch (tracer_type_) {
+ case kTracerTypeARBTimer:
+ glGetQueryObjectui64v(queries_[0], GL_QUERY_RESULT, &beg_stamp);
+ glGetQueryObjectui64v(queries_[1], GL_QUERY_RESULT, &end_stamp);
+ glDeleteQueries(2, queries_);
+ break;
+ case kTracerTypeDisjointTimer:
+ glGetQueryObjectui64vEXT(queries_[0], GL_QUERY_RESULT_EXT, &beg_stamp);
+ glGetQueryObjectui64vEXT(queries_[1], GL_QUERY_RESULT_EXT, &end_stamp);
+ glDeleteQueriesEXT(2, queries_);
+ break;
+
+ default:
+ return;
+ }
- glGetQueryObjectui64v(queries_[1], GL_QUERY_RESULT, &timestamp);
- end_time_ = (timestamp / base::Time::kNanosecondsPerMicrosecond) + offset_;
+ if (discard_trace_)
+ return;
- glDeleteQueries(2, queries_);
+ start_time_ = (beg_stamp / base::Time::kNanosecondsPerMicrosecond) + offset_;
+ end_time_ = (end_stamp / base::Time::kNanosecondsPerMicrosecond) + offset_;
outputter_->Trace(name(), start_time_, end_time_);
}
+void GPUTrace::DiscardTrace() {
+ discard_trace_ = true;
+}
+
GPUTracer::GPUTracer(gles2::GLES2Decoder* decoder)
: gpu_trace_srv_category(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(
TRACE_DISABLED_BY_DEFAULT("gpu.service"))),
@@ -144,13 +212,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 +229,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 +337,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,7 +350,7 @@ void GPUTracer::Process() {
}
void GPUTracer::ProcessTraces() {
- if (!enabled_) {
+ if (tracer_type_ == kTracerTypeInvalid) {
while (!traces_.empty() && traces_.front()->IsAvailable()) {
traces_.front()->Process();
traces_.pop_front();
@@ -302,6 +367,19 @@ 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) {
+ while (!traces_.empty()) {
+ traces_.front()->DiscardTrace();
+ traces_.front()->Process();
+ traces_.pop_front();
+ }
+ }
+ }
+
while (!traces_.empty() && traces_.front()->IsAvailable()) {
traces_.front()->Process();
traces_.pop_front();
@@ -314,23 +392,57 @@ void GPUTracer::ProcessTraces() {
}
void GPUTracer::CalculateTimerOffset() {
- if (enabled_) {
+ if (*gpu_trace_dev_category && tracer_type_ != kTracerTypeInvalid) {
+ 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();
+ glGenQueries(1, &query);
+ glQueryCounter(query, GL_TIMESTAMP);
+ glFinish();
+
+ glGetQueryObjectui64v(query, GL_QUERY_RESULT, &gl_now);
+ glDeleteQueries(1, &query);
+ break;
+
+ case kTracerTypeDisjointTimer:
+ // Clear the disjoint bit before we do any queries.
+ glGetIntegerv(GL_GPU_DISJOINT_EXT, &disjoint_value);
+
+ glFinish();
+ glGenQueriesEXT(1, &query);
+ glQueryCounterEXT(query, GL_TIMESTAMP_EXT);
+ glFinish();
+
+ glGetQueryObjectui64vEXT(query, GL_QUERY_RESULT_EXT, &gl_now);
+ glDeleteQueriesEXT(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;
}
}

Powered by Google App Engine
This is Rietveld 408576698