Index: chrome/browser/webui/gpu_internals_ui.cc |
diff --git a/chrome/browser/webui/gpu_internals_ui.cc b/chrome/browser/webui/gpu_internals_ui.cc |
index 2bcfb9eebb65e8cb949adbf6269530bd3b4abc6b..9bc2840381e183efd3c5a18d7a4e5a93a5afc14b 100644 |
--- a/chrome/browser/webui/gpu_internals_ui.cc |
+++ b/chrome/browser/webui/gpu_internals_ui.cc |
@@ -18,6 +18,7 @@ |
#include "base/string_piece.h" |
#include "base/utf_string_conversions.h" |
#include "base/values.h" |
+#include "base/debug/trace_event.h" |
#include "chrome/browser/browser_process.h" |
#include "chrome/browser/browser_thread.h" |
#include "chrome/browser/dom_ui/chrome_url_data_manager.h" |
@@ -31,6 +32,8 @@ |
#include "chrome/browser/platform_util.h" |
#include "chrome/browser/profiles/profile.h" |
#include "chrome/browser/tab_contents/tab_contents.h" |
+#include "chrome/browser/renderer_host/render_process_host.h" |
+#include "chrome/browser/renderer_host/render_view_host.h" |
#include "chrome/common/chrome_paths.h" |
#include "chrome/common/chrome_version_info.h" |
#include "chrome/common/jstemplate_builder.h" |
@@ -76,12 +79,17 @@ class GpuMessageHandler |
// Mesages |
void OnCallAsync(const ListValue* list); |
+ void OnBeginTracing(const ListValue* list); |
+ void OnBeginToEndTracing(const ListValue* list); |
// Submessages dispatched from OnCallAsync |
Value* OnRequestGpuInfo(const ListValue* list); |
Value* OnRequestClientInfo(const ListValue* list); |
Value* OnRequestLogMessages(const ListValue* list); |
+ // Callbacks from GpuTrace or ChildProcessHosts |
+ void OnTraceDataCollected(const std::string& json_events); |
+ |
// Executes the javascript function |function_name| in the renderer, passing |
// it the argument |value|. |
void CallJavascriptFunction(const std::wstring& function_name, |
@@ -89,6 +97,27 @@ class GpuMessageHandler |
private: |
DISALLOW_COPY_AND_ASSIGN(GpuMessageHandler); |
+ |
+ void OnEndTracingComplete(); |
+ friend class TaskProxy; |
+ |
+ bool traceEnabled_; |
+ int traceNumEndAcksPending_; |
+}; |
+ |
+class TaskProxy : public base::RefCountedThreadSafe<TaskProxy> { |
+ public: |
+ explicit TaskProxy(const base::WeakPtr<GpuMessageHandler>& handler) |
+ : handler_(handler) {} |
+ void OnEndTracingCompleteProxy() { |
+ if (handler_) { |
+ handler_->OnEndTracingComplete(); |
+ } |
+ } |
+ private: |
+ base::WeakPtr<GpuMessageHandler> handler_; |
+ friend class base::RefCountedThreadSafe<TaskProxy>; |
+ DISALLOW_COPY_AND_ASSIGN(TaskProxy); |
}; |
//////////////////////////////////////////////////////////////////////////////// |
@@ -134,10 +163,17 @@ std::string GpuHTMLSource::GetMimeType(const std::string&) const { |
// |
//////////////////////////////////////////////////////////////////////////////// |
-GpuMessageHandler::GpuMessageHandler() { |
+GpuMessageHandler::GpuMessageHandler() |
+ : traceEnabled_(false) |
+ , traceNumEndAcksPending_(0) { |
+ |
} |
-GpuMessageHandler::~GpuMessageHandler() {} |
+GpuMessageHandler::~GpuMessageHandler() { |
+ if (traceEnabled_) { |
+ OnBeginToEndTracing(NULL); |
+ } |
+} |
WebUIMessageHandler* GpuMessageHandler::Attach(WebUI* web_ui) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
@@ -351,6 +387,69 @@ Value* GpuMessageHandler::OnRequestLogMessages(const ListValue*) { |
return GpuProcessHostUIShim::GetInstance()->logMessages(); |
} |
+void GpuMessageHandler::OnBeginTracing(const ListValue* args) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ |
+ traceEnabled_ = true; |
+ base::debug::TraceLog::GetInstance()->SetOutputCallback(NewCallback(this, |
+ &GpuMessageHandler::OnTraceDataCollected)); |
+ base::debug::TraceLog::GetInstance()->SetEnabled(true); |
+ GpuProcessHostUIShim::GetInstance()->SetTraceEnabled(true); |
+ RenderProcessHost::SetTraceEnabled(true); |
+} |
+ |
+void GpuMessageHandler::OnBeginToEndTracing(const ListValue* list) { |
+ DCHECK(traceEnabled_ && !traceNumEndAcksPending_); |
+ |
+ // To end GPU tracing, we have to end tracing on every child process |
+ // and get their ack that we've recieved that data. We do this by |
+ // tracking the number of ack's we're expecting. When this number |
+ // goes to zero, we know we're done. The TRACE_ENDED ack arrives as a |
+ // JSON object in the OnTraceDataCollectedAsJSON. |
+ traceNumEndAcksPending_ = 1; |
+ GpuProcessHostUIShim::GetInstance()->SetTraceEnabled(false); |
+ |
+ traceNumEndAcksPending_ += |
+ RenderProcessHost::SetTraceEnabled(false); |
+} |
+ |
+void GpuMessageHandler::OnEndTracingComplete() { |
+ // TODO(nduca): disable renderer processes, too |
+ base::debug::TraceLog::GetInstance()->SetEnabled(false); |
+ base::debug::TraceLog::GetInstance()->SetOutputCallback(NULL); |
+ traceEnabled_ = false; |
+ web_ui_->CallJavascriptFunction(L"tracingControl.onEndTracingComplete"); |
+} |
+ |
+void GpuMessageHandler::OnTraceDataCollected(const std::string& json_events) { |
+ DCHECK(traceEnabled_); |
+ const char* json_complete = "['TRACE_ENDED']"; |
arv (Not doing code reviews)
2011/02/25 00:51:29
JSON always use double quotes... I looks like this
|
+ if (json_events == json_complete) { |
+ DCHECK(traceNumEndAcksPending_); |
+ traceNumEndAcksPending_ -= 1; |
+ if (traceNumEndAcksPending_ == 0) { |
+ TaskProxy* task = new TaskProxy(AsWeakPtr()); |
+ task->AddRef(); |
+ |
+ BrowserThread::PostTask( |
+ BrowserThread::FILE, FROM_HERE, |
+ NewRunnableMethod( |
+ task, &TaskProxy::OnEndTracingCompleteProxy)); |
+ } |
+ } else { |
+ |
+ std::wstring javascript; |
+ javascript += L"tracingControl.onTraceDataCollected("; |
+ javascript += UTF8ToWide(json_events); |
+ javascript += L");"; |
+ |
+ web_ui_->GetRenderViewHost()->ExecuteJavascriptInWebFrame(string16(), |
+ WideToUTF16Hack(javascript)); |
+ } |
+} |
+ |
+ |
+ |
} // namespace |