| 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..c190122bc9335af3f6b0dacdb2a65a2b4ebf11d2 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:
|
| + 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']";
|
| + 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
|
|
|
|
|
|
|