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

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

Issue 11416117: Hookup the GPUTrace events. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 1 month 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
new file mode 100644
index 0000000000000000000000000000000000000000..3316c82fffc6ec4a853fbdd835607298a212296b
--- /dev/null
+++ b/gpu/command_buffer/service/gpu_tracer.cc
@@ -0,0 +1,361 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "gpu/command_buffer/service/gpu_tracer.h"
+
+#include "base/threading/non_thread_safe.h"
+#include "base/threading/thread.h"
+#include "base/time.h"
+#include "ui/gl/gl_bindings.h"
+
+namespace gpu {
+namespace gles2 {
+
+class GPUTracer::Trace {
+ public:
+ virtual ~Trace() {};
+
+ virtual void Start() = 0;
+ virtual void End() = 0;
+
+ // True if the the results of this query are available.
+ virtual bool IsAvailable() = 0;
+
+ const char* name() {
+ return name_.c_str();
+ }
+
+ protected:
+ explicit Trace(const std::string& name) : name_(name) {}
+
+ virtual int64 start_time() = 0;
+ virtual int64 end_time() = 0;
+
+ private:
+ friend GPUTracer::Outputter;
jonathan.backer 2012/11/23 18:55:41 Why friend? To read the name? You could hide the T
dsinclair 2012/11/23 21:13:56 Friend'd to give access to the start_time and end_
+
+ std::string name_;
+
+ DISALLOW_COPY_AND_ASSIGN(Trace);
+};
+
+class GPUTracer::Outputter
+ : public base::Thread,
+ public base::NonThreadSafe {
jonathan.backer 2012/11/23 18:55:41 base::NonThreadSafe is for sanity checking that yo
dsinclair 2012/11/23 21:13:56 copy-paste. Removed.
+ public:
+ static linked_ptr<GPUTracer::Outputter> Create(const std::string& name) {
jonathan.backer 2012/11/23 18:55:41 Why a linked_ptr? And why a factory?
dsinclair 2012/11/23 21:13:56 Was half an implementation of something else. Chan
+ linked_ptr<GPUTracer::Outputter> out = linked_ptr<GPUTracer::Outputter>(
+ new GPUTracer::Outputter(name));
+
+ // We need to start/stop the thread in order to get a thread_id.
+ out->Start();
+ out->Stop();
+ return out;
+ }
+
+ virtual ~Outputter() {}
+
+ virtual void Output(GPUTracer::Trace* trace) {
+ // TODO(dsinclair): Change to TRACE_EVENT
+ LOG(INFO) << "Thread " << thread_id() << ": "
+ << thread_name() << ": "
+ << trace->name() << ": "
+ << trace_start_time(trace) << " "
+ << trace_end_time(trace);
+ }
+
+ protected:
+ explicit Outputter(const std::string& name) : base::Thread(name.c_str()) {
+ }
+
+
+ int64 trace_start_time(GPUTracer::Trace* trace) {
+ return trace->start_time();
+ }
+
+ int64 trace_end_time(GPUTracer::Trace* trace) {
+ return trace->end_time();
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Outputter);
+};
+
+namespace {
+
+static const unsigned int kGPUTraceMaxQueueSize = 1024;
+
+class GPUTracerSystemTime : public GPUTracer {
+ public:
+ GPUTracerSystemTime();
+ ~GPUTracerSystemTime();
+
+ linked_ptr<GPUTracer::Trace> CreateTrace(const std::string& name) OVERRIDE;
+
+ private:
+ class Trace : public GPUTracer::Trace {
+ public:
+ explicit Trace(const std::string& name);
+ ~Trace() OVERRIDE;
+
+ void Start() OVERRIDE;
+ void End() OVERRIDE;
+ bool IsAvailable() OVERRIDE;
+
+ protected:
+ int64 start_time() OVERRIDE;
+ int64 end_time() OVERRIDE;
+
+ private:
+ bool has_ended_;
+ base::TimeTicks start_time_;
+ base::TimeTicks end_time_;
+
+ DISALLOW_COPY_AND_ASSIGN(Trace);
+ };
+
+ DISALLOW_COPY_AND_ASSIGN(GPUTracerSystemTime);
+};
+
+class GPUTracerARBTimerQuery : public GPUTracer {
+ public:
+ GPUTracerARBTimerQuery();
+ ~GPUTracerARBTimerQuery();
+
+ linked_ptr<GPUTracer::Trace> CreateTrace(const std::string& name) OVERRIDE;
+
+ private:
+ class Trace : public GPUTracer::Trace {
+ public:
+ explicit Trace(const std::string& name);
+ ~Trace() OVERRIDE;
+
+ void Start() OVERRIDE;
+ void End() OVERRIDE;
+ bool IsAvailable() OVERRIDE;
+
+ protected:
+ int64 start_time() OVERRIDE;
+ int64 end_time() OVERRIDE;
+
+ private:
+ unsigned int start_timer_;
+ unsigned int end_timer_;
+
+ DISALLOW_COPY_AND_ASSIGN(Trace);
+ };
+
+ class Outputter : public GPUTracer::Outputter {
+ public:
+ static linked_ptr<GPUTracer::Outputter> Create(const std::string& name,
+ int64 timer_offset) {
+ linked_ptr<GPUTracer::Outputter> out = linked_ptr<GPUTracer::Outputter>(
+ new GPUTracerARBTimerQuery::Outputter(name, timer_offset));
+
+ // We need to start/stop the thread in order to get a thread_id.
+ out->Start();
+ out->Stop();
+ return out;
+ }
+
+ ~Outputter() {}
+
+ void Output(GPUTracer::Trace* trace) OVERRIDE {
+ // TODO(dsinclair): Change to TRACE_EVENT
+ LOG(INFO) << "Thread " << thread_id() << ": "
+ << thread_name() << ": "
+ << trace->name() << ": "
+ << trace_start_time(trace) << " "
+ << trace_end_time(trace);
+ }
+
+ protected:
+ explicit Outputter(const std::string& name, int64 timer_offset)
+ : GPUTracer::Outputter(name.c_str()),
+ timer_offset_(timer_offset) {
+ }
+
+ int64 trace_start_time(GPUTracer::Trace* trace) {
+ return GPUTracer::Outputter::trace_start_time(trace) + timer_offset_;
+ }
+
+ int64 trace_end_time(GPUTracer::Trace* trace) {
+ return GPUTracer::Outputter::trace_end_time(trace) + timer_offset_;
+ }
+
+ private:
+ int64 timer_offset_;
+
+ DISALLOW_COPY_AND_ASSIGN(Outputter);
+ };
+
+ DISALLOW_COPY_AND_ASSIGN(GPUTracerARBTimerQuery);
+};
+
+GPUTracerSystemTime::GPUTracerSystemTime() : GPUTracer() {
+ output_ = linked_ptr<GPUTracer::Outputter>(
+ GPUTracer::Outputter::Create("SystemTime"));
+}
+
+GPUTracerSystemTime::~GPUTracerSystemTime() {
+}
+
+linked_ptr<GPUTracer::Trace> GPUTracerSystemTime::CreateTrace(
+ const std::string& name) {
+ return linked_ptr<GPUTracer::Trace>(new GPUTracerSystemTime::Trace(name));
+}
+
+GPUTracerSystemTime::Trace::Trace(const std::string& name) :
+ GPUTracer::Trace(name),
+ has_ended_(false),
+ start_time_(),
+ end_time_() {
+}
+
+GPUTracerSystemTime::Trace::~Trace() {
+}
+
+void GPUTracerSystemTime::Trace::Start() {
+ start_time_ = base::TimeTicks::NowFromSystemTraceTime();
+}
+
+int64 GPUTracerSystemTime::Trace::start_time() {
+ return start_time_.ToInternalValue();
+}
+
+void GPUTracerSystemTime::Trace::End() {
+ end_time_ = base::TimeTicks::NowFromSystemTraceTime();
+ has_ended_ = true;
+}
+
+int64 GPUTracerSystemTime::Trace::end_time() {
+ return end_time_.ToInternalValue();
+}
+
+bool GPUTracerSystemTime::Trace::IsAvailable() {
+ return has_ended_;
+}
+
+GPUTracerARBTimerQuery::GPUTracerARBTimerQuery() : GPUTracer() {
+ // TODO(dsinclair): Change to glGetInteger64v.
+ GLuint64 gl_now = 0;
+ GLuint query;
+ glGenQueries(1, &query);
+
+ // Flush the pipeline so our query is more accurate.
+ glFinish();
+
+ glQueryCounter(query, GL_TIMESTAMP);
+ glGetQueryObjectui64v(query, GL_QUERY_RESULT, &gl_now);
+ glDeleteQueries(1, &query);
+
+ gl_now /= base::Time::kNanosecondsPerMicrosecond;
+
+ base::TimeTicks system_now = base::TimeTicks::NowFromSystemTraceTime();
+
+ int64 time_offset = system_now.ToInternalValue() - gl_now;
+ output_ = linked_ptr<GPUTracer::Outputter>(
+ GPUTracerARBTimerQuery::Outputter::Create("GL_ARB_timer_query",
+ time_offset));
+}
+
+GPUTracerARBTimerQuery::~GPUTracerARBTimerQuery() {
+}
+
+linked_ptr<GPUTracer::Trace> GPUTracerARBTimerQuery::CreateTrace(
+ const std::string& name) {
+ return linked_ptr<GPUTracer::Trace>(new GPUTracerARBTimerQuery::Trace(name));
+}
+
+GPUTracerARBTimerQuery::Trace::Trace(const std::string& name) :
+ GPUTracer::Trace(name),
+ start_timer_(0),
+ end_timer_(0) {
+ GLuint queries[2];
+ glGenQueries(2, queries);
+
+ start_timer_ = queries[0];
+ end_timer_ = queries[1];
+}
+
+GPUTracerARBTimerQuery::Trace::~Trace() {
+ GLuint queries[] = {start_timer_, end_timer_};
+ glDeleteQueries(2, queries);
+}
+
+void GPUTracerARBTimerQuery::Trace::Start() {
+ glQueryCounter(start_timer_, GL_TIMESTAMP);
+}
+
+int64 GPUTracerARBTimerQuery::Trace::start_time() {
+ GLint64 timestamp;
+ glGetQueryObjecti64v(start_timer_, GL_QUERY_RESULT, &timestamp);
+ return timestamp / base::Time::kNanosecondsPerMicrosecond;
+}
+
+void GPUTracerARBTimerQuery::Trace::End() {
+ glQueryCounter(end_timer_, GL_TIMESTAMP);
+}
+
+int64 GPUTracerARBTimerQuery::Trace::end_time() {
+ GLint64 timestamp;
+ glGetQueryObjecti64v(end_timer_, GL_QUERY_RESULT, &timestamp);
+ return timestamp / base::Time::kNanosecondsPerMicrosecond;
+}
+
+bool GPUTracerARBTimerQuery::Trace::IsAvailable() {
+ GLint done = 0;
+ glGetQueryObjectiv(end_timer_, GL_QUERY_RESULT_AVAILABLE, &done);
+ return !!done;
+}
+
+} // namespace
+
+scoped_ptr<GPUTracer> GPUTracer::create() {
+ if (gfx::g_driver_gl.ext.b_GL_ARB_timer_query)
+ return scoped_ptr<GPUTracer>(new GPUTracerARBTimerQuery());
+
+ return scoped_ptr<GPUTracer>(new GPUTracerSystemTime());
+}
+
+GPUTracer::GPUTracer() {
+}
+
+GPUTracer::~GPUTracer() {
+}
+
+bool GPUTracer::Begin(const std::string& name) {
+ // Make sure we are not nesting trace commands.
+ if (current_trace_.get() != NULL)
+ return false;
+
+ current_trace_ = CreateTrace(name);
+ current_trace_->Start();
+ return true;
+}
+
+bool GPUTracer::End() {
+ if (current_trace_.get() == NULL) {
+ return false;
+ }
+
+ current_trace_->End();
+ traces_.push_back(current_trace_);
+ current_trace_ = linked_ptr<GPUTracer::Trace>(NULL);
jonathan.backer 2012/11/23 18:55:41 I think that you can just call .reset() here.
dsinclair 2012/11/23 21:13:56 Done.
+
+ if (traces_.size() > kGPUTraceMaxQueueSize)
+ Process();
+
+ return true;
+}
+
+void GPUTracer::Process() {
+ while (!traces_.empty() && traces_.front()->IsAvailable()) {
+ output_->Output(traces_.front().get());
+ traces_.pop_front();
+ }
+}
+
+} // namespace gles2
+} // namespace gpu

Powered by Google App Engine
This is Rietveld 408576698