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

Unified Diff: gpu/common/gpu_trace_event.cc

Issue 6691013: Introduce gpu_trace_event for gpu performance analysis. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 9 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/common/gpu_trace_event.cc
diff --git a/gpu/common/gpu_trace_event.cc b/gpu/common/gpu_trace_event.cc
new file mode 100644
index 0000000000000000000000000000000000000000..a22b8de5a9354b5f9a58157e46355b0029bb60b3
--- /dev/null
+++ b/gpu/common/gpu_trace_event.cc
@@ -0,0 +1,216 @@
+// Copyright (c) 2010 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/common/gpu_trace_event.h"
+
+#include "base/format_macros.h"
+#include "base/process_util.h"
+#include "base/stringprintf.h"
+#include "base/utf_string_conversions.h"
+#include "base/time.h"
+
+#define USE_UNRELIABLE_NOW
+
+using namespace base;
+
+namespace gpu {
+
+// Controls the number of trace events we will buffer in-memory
+// before flushing them.
+#define TRACE_EVENT_BUFFER_SIZE 16384
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// TraceLog::Category
+//
+////////////////////////////////////////////////////////////////////////////////
+TraceCategory::TraceCategory(const char* name, bool enabled)
+ : name_(name) {
+ base::subtle::NoBarrier_Store(&enabled_,
+ static_cast<base::subtle::Atomic32>(enabled));
+}
+
+TraceCategory::~TraceCategory() {
+ base::subtle::NoBarrier_Store(&enabled_,
+ static_cast<base::subtle::Atomic32>(0));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// TraceEvent
+//
+////////////////////////////////////////////////////////////////////////////////
+
+namespace {
+const char* GetPhaseStr(TraceEventPhase phase) {
+ if (phase == GPU_TRACE_EVENT_PHASE_BEGIN) {
+ return "B";
+ } else if (phase == GPU_TRACE_EVENT_PHASE_INSTANT) {
+ return "I";
+ } else if (phase == GPU_TRACE_EVENT_PHASE_END) {
+ return "E";
+ } else {
+ DCHECK(false);
+ return "?";
+ }
+}
+}
+
+void TraceEvent::AppendAsJSON(std::string* out,
+ const std::vector<TraceEvent>& events) {
+ *out += "[";
+ for (size_t i = 0; i < events.size(); ++i) {
+ if (i > 0)
+ *out += ",";
+ events[i].AppendAsJSON(out);
+ }
+ *out += "]";
+}
+
+void TraceEvent::AppendAsJSON(std::string* out) const {
+ int nargs = 0;
+ for (int i = 0; i < TRACE_MAX_NUM_ARGS; ++i) {
+ if (argNames[i] == NULL)
+ break;
+ nargs += 1;
+ }
+
+ const char* phaseStr = GetPhaseStr(phase);
+ int64 time_int64 = timestamp.ToInternalValue();
+ long long unsigned int time_llui =
+ static_cast<long long unsigned int>(time_int64);
+ StringAppendF(out,
+ "{cat:'%s',pid:%i,tid:%i,ts:0x%llx,ph:'%s',name:'%s',args:{",
+ category->name(),
+ static_cast<int>(processId),
+ static_cast<int>(threadId),
+ time_llui,
+ phaseStr,
+ name);
+ for (int i = 0; i < nargs; ++i) {
+ if (i > 0)
+ *out += ",";
+ *out += argNames[i];
+ *out += ":'";
+ *out += argValues[i];
+ *out += "'";
+ }
+ *out += "}}";
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// TraceLog
+//
+////////////////////////////////////////////////////////////////////////////////
+
+// static
+TraceLog* TraceLog::GetInstance() {
+ return Singleton<TraceLog, StaticMemorySingletonTraits<TraceLog> >::get();
+}
+
+TraceLog::TraceLog()
+ : enabled_(false)
+{
+ logged_events_.reserve(1024);
+}
+
+TraceLog::~TraceLog() {
+}
+
+TraceCategory* TraceLog::GetCategory(const char* name) {
+ AutoLock lock(lock_);
+ // TODO(nduca) replace with a hash_map
Ken Russell (switch to Gerrit) 2011/03/14 23:57:35 Colon after TODO (e.g., TODO(nduca): )
nduca 2011/03/15 01:21:40 Done.
+ for (int i = categories_.size() - 1; i >= 0; i-- ) {
+ if (strcmp(categories_[i]->name(), name) == 0)
+ return categories_[i];
+ }
+ TraceCategory* category = new TraceCategory(name, enabled_);
+ categories_.push_back(category);
+ return category;
+}
+
+void TraceLog::SetEnabled(bool enabled) {
+ AutoLock lock(lock_);
+ if (enabled == enabled_)
+ return;
+ if (enabled) {
+ /* enable all categories */
Ken Russell (switch to Gerrit) 2011/03/14 23:57:35 Use C++ style comments instead?
nduca 2011/03/15 01:21:40 Done.
+ enabled_ = true;
+ for (size_t i = 0; i < categories_.size(); i++) {
+ base::subtle::NoBarrier_Store(&categories_[i]->enabled_,
+ static_cast<base::subtle::Atomic32>(1));
+ }
+ } else {
+ /* disable all categories */
+ for (size_t i = 0; i < categories_.size(); i++) {
+ base::subtle::NoBarrier_Store(&categories_[i]->enabled_,
+ static_cast<base::subtle::Atomic32>(0));
+ }
+ enabled_ = false;
+ FlushWithLockAlreadyHeld();
+ }
+}
+
+void TraceLog::SetOutputCallback(TraceLog::OutputCallback* cb) {
+ AutoLock lock(lock_);
+ if (enabled_) {
+ FlushWithLockAlreadyHeld();
+ }
+ output_callback_.reset(cb);
+}
+
+void TraceLog::AddRemotelyCollectedData(const std::string& json_events) {
+ AutoLock lock(lock_);
+ if (output_callback_.get())
+ output_callback_->Run(json_events);
+}
+
+void TraceLog::Flush() {
+ AutoLock lock(lock_);
+ FlushWithLockAlreadyHeld();
+}
+
+void TraceLog::FlushWithLockAlreadyHeld() {
+ if (output_callback_.get() && logged_events_.size()) {
+ std::string json_events;
+ TraceEvent::AppendAsJSON(&json_events, logged_events_);
+ output_callback_->Run(json_events);
+ }
+ logged_events_.erase(logged_events_.begin(), logged_events_.end());
+}
+
+void TraceLog::AddTraceEvent(TraceEventPhase phase,
+ const char* file, int line,
+ TraceCategory* category,
+ const char* name,
+ const char* arg1name, const char* arg1val,
+ const char* arg2name, const char* arg2val) {
+ DCHECK(file && name);
+#ifdef USE_UNRELIABLE_NOW
+ TimeTicks now = TimeTicks::HighResNow();
+#else
+ TimeTicks now = TimeTicks::Now();
+#endif
+ //static_cast<unsigned long>(base::GetCurrentProcId()),
+ AutoLock lock(lock_);
+ logged_events_.push_back(TraceEvent());
+ TraceEvent& event = logged_events_.back();
+ event.processId = static_cast<unsigned long>(base::GetCurrentProcId());
+ event.threadId = PlatformThread::CurrentId();
+ event.timestamp = now;
+ event.phase = phase;
+ event.category = category;
+ event.name = name;
+ event.argNames[0] = arg1name;
+ event.argValues[0] = arg1name ? arg1val : "";
+ event.argNames[1] = arg2name;
+ event.argValues[1] = arg2name ? arg2val : "";
+ COMPILE_ASSERT(TRACE_MAX_NUM_ARGS == 2, TraceEvent_arc_count_out_of_sync);
+
+ if (logged_events_.size() > TRACE_EVENT_BUFFER_SIZE)
+ FlushWithLockAlreadyHeld();
+}
+
+} // namespace gpu
« gpu/common/gpu_trace_event.h ('K') | « gpu/common/gpu_trace_event.h ('k') | gpu/gpu.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698