summaryrefslogtreecommitdiffstats
path: root/content/common
diff options
context:
space:
mode:
authoralph@chromium.org <alph@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-11-21 06:01:36 +0000
committeralph@chromium.org <alph@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-11-21 06:01:36 +0000
commit2bb3b8e022870b6ae42abed5d8a921b6b08f1c8c (patch)
tree60a746b3099b1f220eccc9979d7bd1bbfdf8111e /content/common
parente2693eab682106cfcfae8c767db5d3050804ec50 (diff)
downloadchromium_src-2bb3b8e022870b6ae42abed5d8a921b6b08f1c8c.zip
chromium_src-2bb3b8e022870b6ae42abed5d8a921b6b08f1c8c.tar.gz
chromium_src-2bb3b8e022870b6ae42abed5d8a921b6b08f1c8c.tar.bz2
DevTools: Add an instrumentation event to track GPU utilization
Add an instrumentation event to GPU command buffer to enable GPU process utilization tracking in DevTools. The collected events are then passed to the DevToolsAgent peer at the inspected renderer process. The Blink counterpart is at https://codereview.chromium.org/46663010/ TBR=jln BUG=298951 Review URL: https://codereview.chromium.org/64173003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@236403 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/common')
-rw-r--r--content/common/devtools_messages.h12
-rw-r--r--content/common/gpu/client/gpu_channel_host.h2
-rw-r--r--content/common/gpu/devtools_gpu_agent.cc78
-rw-r--r--content/common/gpu/devtools_gpu_agent.h51
-rw-r--r--content/common/gpu/devtools_gpu_instrumentation.cc50
-rw-r--r--content/common/gpu/devtools_gpu_instrumentation.h65
-rw-r--r--content/common/gpu/gpu_channel.cc15
-rw-r--r--content/common/gpu/gpu_channel.h4
-rw-r--r--content/common/gpu/gpu_channel_manager.h6
-rw-r--r--content/common/gpu/gpu_command_buffer_stub.cc2
-rw-r--r--content/common/gpu/gpu_messages.h8
11 files changed, 292 insertions, 1 deletions
diff --git a/content/common/devtools_messages.h b/content/common/devtools_messages.h
index b8d4c7e..5d67c22 100644
--- a/content/common/devtools_messages.h
+++ b/content/common/devtools_messages.h
@@ -122,6 +122,18 @@ IPC_MESSAGE_ROUTED0(DevToolsHostMsg_ClearBrowserCache)
// Clears browser cookies.
IPC_MESSAGE_ROUTED0(DevToolsHostMsg_ClearBrowserCookies)
+//-----------------------------------------------------------------------------
+// These are messages sent from the GPU process to the inspected renderer.
+
+IPC_STRUCT_BEGIN(GpuTaskInfo)
+ IPC_STRUCT_MEMBER(double, timestamp)
+ IPC_STRUCT_MEMBER(int, phase)
+ IPC_STRUCT_MEMBER(unsigned, owner_pid)
+IPC_STRUCT_END()
+
+// Recorded events are passed in chunks to the renderer process.
+IPC_MESSAGE_ROUTED1(DevToolsAgentMsg_GpuTasksChunk,
+ std::vector<GpuTaskInfo> /* gpu_tasks */)
//-----------------------------------------------------------------------------
// These are messages sent from the inspected page renderer to the worker
diff --git a/content/common/gpu/client/gpu_channel_host.h b/content/common/gpu/client/gpu_channel_host.h
index f248c77..37f5415 100644
--- a/content/common/gpu/client/gpu_channel_host.h
+++ b/content/common/gpu/client/gpu_channel_host.h
@@ -229,7 +229,7 @@ class GpuChannelHost : public IPC::Sender,
typedef base::hash_map<int, GpuListenerInfo> ListenerMap;
ListenerMap listeners_;
- // Protexts all fields below this one.
+ // Protects all fields below this one.
mutable base::Lock lock_;
// Whether the channel has been lost.
diff --git a/content/common/gpu/devtools_gpu_agent.cc b/content/common/gpu/devtools_gpu_agent.cc
new file mode 100644
index 0000000..315be90
--- /dev/null
+++ b/content/common/gpu/devtools_gpu_agent.cc
@@ -0,0 +1,78 @@
+// Copyright 2013 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 "content/common/gpu/devtools_gpu_agent.h"
+
+#include "base/logging.h"
+#include "content/common/devtools_messages.h"
+#include "content/common/gpu/gpu_channel.h"
+#include "content/common/gpu/gpu_channel_manager.h"
+
+namespace content {
+
+DevToolsGpuAgent::DevToolsGpuAgent(GpuChannel* gpu_channel) :
+ gpu_channel_(gpu_channel),
+ route_id_(MSG_ROUTING_NONE) {
+}
+
+DevToolsGpuAgent::~DevToolsGpuAgent() {
+}
+
+void DevToolsGpuAgent::StartEventsRecording(int32* route_id) {
+ DCHECK(CalledOnValidThread());
+ if (route_id_ != MSG_ROUTING_NONE) {
+ // Events recording is already in progress, so "fail" the call by
+ // returning MSG_ROUTING_NONE as the route id.
+ *route_id = MSG_ROUTING_NONE;
+ return;
+ }
+ route_id_ = gpu_channel_->GenerateRouteID();
+ *route_id = route_id_;
+ tasks_.reset(new GpuTaskInfoList());
+ GpuEventsDispatcher* dispatcher =
+ gpu_channel_->gpu_channel_manager()->gpu_devtools_events_dispatcher();
+ dispatcher->AddProcessor(this);
+}
+
+void DevToolsGpuAgent::StopEventsRecording() {
+ DCHECK(CalledOnValidThread());
+ if (route_id_ == MSG_ROUTING_NONE)
+ return;
+ GpuEventsDispatcher* dispatcher =
+ gpu_channel_->gpu_channel_manager()->gpu_devtools_events_dispatcher();
+ dispatcher->RemoveProcessor(this);
+ route_id_ = MSG_ROUTING_NONE;
+}
+
+void DevToolsGpuAgent::ProcessEvent(
+ TimeTicks timestamp,
+ GpuEventsDispatcher::EventPhase phase,
+ int owner_pid) {
+ DCHECK(CalledOnValidThread());
+ if (route_id_ == MSG_ROUTING_NONE)
+ return;
+
+ GpuTaskInfo task;
+ task.timestamp = (timestamp - TimeTicks()).InSecondsF();
+ task.phase = phase;
+ task.owner_pid = owner_pid;
+
+ const int kFlushIntervalMs = 100;
+ const unsigned kMaxPendingItems = 100;
+ if (!tasks_->empty() &&
+ ((timestamp - last_flush_time_).InMilliseconds() >= kFlushIntervalMs ||
+ tasks_->size() >= kMaxPendingItems)) {
+ Send(new DevToolsAgentMsg_GpuTasksChunk(route_id_, *tasks_));
+ tasks_->clear();
+ last_flush_time_ = timestamp;
+ }
+ tasks_->push_back(task);
+}
+
+bool DevToolsGpuAgent::Send(IPC::Message* msg) {
+ scoped_ptr<IPC::Message> message(msg);
+ return gpu_channel_ && gpu_channel_->Send(message.release());
+}
+
+} // namespace content
diff --git a/content/common/gpu/devtools_gpu_agent.h b/content/common/gpu/devtools_gpu_agent.h
new file mode 100644
index 0000000..94174bf
--- /dev/null
+++ b/content/common/gpu/devtools_gpu_agent.h
@@ -0,0 +1,51 @@
+// Copyright 2013 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.
+
+#ifndef CONTENT_COMMON_GPU_DEVTOOLS_GPU_AGENT_H_
+#define CONTENT_COMMON_GPU_DEVTOOLS_GPU_AGENT_H_
+
+#include "base/memory/scoped_ptr.h"
+#include "base/threading/non_thread_safe.h"
+#include "base/time/time.h"
+#include "content/common/gpu/devtools_gpu_instrumentation.h"
+
+using base::TimeTicks;
+struct GpuTaskInfo;
+
+namespace IPC {
+class Message;
+}
+
+namespace content {
+
+class GpuChannel;
+
+class DevToolsGpuAgent : public base::NonThreadSafe {
+ public:
+ explicit DevToolsGpuAgent(GpuChannel* gpu_channel);
+ virtual ~DevToolsGpuAgent();
+
+ void ProcessEvent(TimeTicks timestamp,
+ GpuEventsDispatcher::EventPhase,
+ int owner_pid);
+
+ void StartEventsRecording(int32* route_id);
+ void StopEventsRecording();
+
+ private:
+ typedef std::vector<GpuTaskInfo> GpuTaskInfoList;
+
+ bool Send(IPC::Message* msg);
+
+ GpuChannel* gpu_channel_;
+ scoped_ptr<GpuTaskInfoList> tasks_;
+ TimeTicks last_flush_time_;
+ int32 route_id_;
+
+ DISALLOW_COPY_AND_ASSIGN(DevToolsGpuAgent);
+};
+
+} // namespace content
+
+#endif // CONTENT_COMMON_GPU_DEVTOOLS_GPU_AGENT_H_
diff --git a/content/common/gpu/devtools_gpu_instrumentation.cc b/content/common/gpu/devtools_gpu_instrumentation.cc
new file mode 100644
index 0000000..c8d688c
--- /dev/null
+++ b/content/common/gpu/devtools_gpu_instrumentation.cc
@@ -0,0 +1,50 @@
+// Copyright 2013 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 "content/common/gpu/devtools_gpu_instrumentation.h"
+
+#include "base/logging.h"
+#include "base/time/time.h"
+#include "content/common/gpu/devtools_gpu_agent.h"
+#include "content/common/gpu/gpu_channel.h"
+#include "content/common/gpu/gpu_channel_manager.h"
+
+namespace content {
+
+bool GpuEventsDispatcher::enabled_ = false;
+
+GpuEventsDispatcher::GpuEventsDispatcher() {
+}
+
+GpuEventsDispatcher::~GpuEventsDispatcher() {
+}
+
+void GpuEventsDispatcher::AddProcessor(DevToolsGpuAgent* processor) {
+ DCHECK(CalledOnValidThread());
+ processors_.push_back(processor);
+ enabled_ = !processors_.empty();
+}
+
+void GpuEventsDispatcher::RemoveProcessor(DevToolsGpuAgent* processor) {
+ DCHECK(CalledOnValidThread());
+ processors_.erase(
+ std::remove(processors_.begin(), processors_.end(), processor),
+ processors_.end());
+ enabled_ = !processors_.empty();
+}
+
+// static
+void GpuEventsDispatcher::DoFireEvent(EventPhase phase, GpuChannel* channel) {
+ TimeTicks timestamp = base::TimeTicks::NowFromSystemTraceTime();
+ GpuEventsDispatcher* self =
+ channel->gpu_channel_manager()->gpu_devtools_events_dispatcher();
+ DCHECK(self->CalledOnValidThread());
+ unsigned owner_pid = channel->renderer_pid();
+ std::vector<DevToolsGpuAgent*>::iterator it;
+ for (it = self->processors_.begin(); it != self->processors_.end(); ++it) {
+ (*it)->ProcessEvent(timestamp, phase, owner_pid);
+ }
+}
+
+} // namespace
diff --git a/content/common/gpu/devtools_gpu_instrumentation.h b/content/common/gpu/devtools_gpu_instrumentation.h
new file mode 100644
index 0000000..d415dec
--- /dev/null
+++ b/content/common/gpu/devtools_gpu_instrumentation.h
@@ -0,0 +1,65 @@
+// Copyright 2013 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.
+
+#ifndef CONTENT_COMMON_GPU_DEVTOOLS_GPU_INSTRUMENTATION_H_
+#define CONTENT_COMMON_GPU_DEVTOOLS_GPU_INSTRUMENTATION_H_
+
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/threading/non_thread_safe.h"
+
+namespace content {
+
+class DevToolsGpuAgent;
+class GpuChannel;
+
+class GpuEventsDispatcher : public base::NonThreadSafe {
+ public:
+ enum EventPhase {
+ kEventStart,
+ kEventFinish
+ };
+
+ GpuEventsDispatcher();
+ ~GpuEventsDispatcher();
+
+ void AddProcessor(DevToolsGpuAgent* processor);
+ void RemoveProcessor(DevToolsGpuAgent* processor);
+
+ static void FireEvent(EventPhase phase, GpuChannel* channel) {
+ if (!IsEnabled())
+ return;
+ DoFireEvent(phase, channel);
+ }
+
+private:
+ static bool IsEnabled() { return enabled_; }
+ static void DoFireEvent(EventPhase, GpuChannel*);
+
+ static bool enabled_;
+ std::vector<DevToolsGpuAgent*> processors_;
+};
+
+namespace devtools_gpu_instrumentation {
+
+class ScopedGpuTask {
+ public:
+ explicit ScopedGpuTask(GpuChannel* channel) :
+ channel_(channel) {
+ GpuEventsDispatcher::FireEvent(GpuEventsDispatcher::kEventStart, channel_);
+ }
+ ~ScopedGpuTask() {
+ GpuEventsDispatcher::FireEvent(GpuEventsDispatcher::kEventFinish, channel_);
+ }
+ private:
+ GpuChannel* channel_;
+ DISALLOW_COPY_AND_ASSIGN(ScopedGpuTask);
+};
+
+} // namespace devtools_gpu_instrumentation
+
+} // namespace content
+
+#endif // CONTENT_COMMON_GPU_DEVTOOLS_GPU_INSTRUMENTATION_H_
diff --git a/content/common/gpu/gpu_channel.cc b/content/common/gpu/gpu_channel.cc
index fe6bb5b..2e8fd78 100644
--- a/content/common/gpu/gpu_channel.cc
+++ b/content/common/gpu/gpu_channel.cc
@@ -18,6 +18,7 @@
#include "base/rand_util.h"
#include "base/strings/string_util.h"
#include "base/timer/timer.h"
+#include "content/common/gpu/devtools_gpu_agent.h"
#include "content/common/gpu/gpu_channel_manager.h"
#include "content/common/gpu/gpu_messages.h"
#include "content/common/gpu/media/gpu_video_encode_accelerator.h"
@@ -487,6 +488,8 @@ bool GpuChannel::Init(base::MessageLoopProxy* io_message_loop,
io_message_loop_ = io_message_loop;
channel_->AddFilter(filter_.get());
+ devtools_gpu_agent_.reset(new DevToolsGpuAgent(this));
+
return true;
}
@@ -757,6 +760,10 @@ bool GpuChannel::OnControlMessageReceived(const IPC::Message& msg) {
IPC_MESSAGE_HANDLER(GpuChannelMsg_CreateVideoEncoder, OnCreateVideoEncoder)
IPC_MESSAGE_HANDLER(GpuChannelMsg_DestroyVideoEncoder,
OnDestroyVideoEncoder)
+ IPC_MESSAGE_HANDLER(GpuChannelMsg_DevToolsStartEventsRecording,
+ OnDevToolsStartEventsRecording)
+ IPC_MESSAGE_HANDLER(GpuChannelMsg_DevToolsStopEventsRecording,
+ OnDevToolsStopEventsRecording)
#if defined(OS_ANDROID)
IPC_MESSAGE_HANDLER(GpuChannelMsg_RegisterStreamTextureProxy,
OnRegisterStreamTextureProxy)
@@ -918,6 +925,14 @@ void GpuChannel::OnDestroyVideoEncoder(int32 route_id) {
video_encoders_.Remove(route_id);
}
+void GpuChannel::OnDevToolsStartEventsRecording(int32* route_id) {
+ devtools_gpu_agent_->StartEventsRecording(route_id);
+}
+
+void GpuChannel::OnDevToolsStopEventsRecording() {
+ devtools_gpu_agent_->StopEventsRecording();
+}
+
#if defined(OS_ANDROID)
void GpuChannel::OnRegisterStreamTextureProxy(
int32 stream_id, int32* route_id) {
diff --git a/content/common/gpu/gpu_channel.h b/content/common/gpu/gpu_channel.h
index b02fafb..2808ed4 100644
--- a/content/common/gpu/gpu_channel.h
+++ b/content/common/gpu/gpu_channel.h
@@ -49,6 +49,7 @@ class StreamTextureManagerAndroid;
#endif
namespace content {
+class DevToolsGpuAgent;
class GpuChannelManager;
class GpuChannelMessageFilter;
struct GpuRenderingStats;
@@ -184,6 +185,8 @@ class GpuChannel : public IPC::Listener,
void OnDestroyCommandBuffer(int32 route_id);
void OnCreateVideoEncoder(int32* route_id);
void OnDestroyVideoEncoder(int32 route_id);
+ void OnDevToolsStartEventsRecording(int32* route_id);
+ void OnDevToolsStopEventsRecording();
#if defined(OS_ANDROID)
// Register the StreamTextureProxy class with the gpu process so that all
@@ -262,6 +265,7 @@ class GpuChannel : public IPC::Listener,
scoped_refptr<GpuChannelMessageFilter> filter_;
scoped_refptr<base::MessageLoopProxy> io_message_loop_;
+ scoped_ptr<DevToolsGpuAgent> devtools_gpu_agent_;
size_t num_stubs_descheduled_;
diff --git a/content/common/gpu/gpu_channel_manager.h b/content/common/gpu/gpu_channel_manager.h
index f01a1c5..eb4d224 100644
--- a/content/common/gpu/gpu_channel_manager.h
+++ b/content/common/gpu/gpu_channel_manager.h
@@ -15,6 +15,7 @@
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop_proxy.h"
#include "build/build_config.h"
+#include "content/common/gpu/devtools_gpu_instrumentation.h"
#include "content/common/gpu/gpu_memory_manager.h"
#include "ipc/ipc_listener.h"
#include "ipc/ipc_sender.h"
@@ -91,6 +92,10 @@ class GpuChannelManager : public IPC::Listener,
GpuMemoryManager* gpu_memory_manager() { return &gpu_memory_manager_; }
+ GpuEventsDispatcher* gpu_devtools_events_dispatcher() {
+ return &gpu_devtools_events_dispatcher_;
+ }
+
GpuChannel* LookupChannel(int32 client_id);
SyncPointManager* sync_point_manager() { return sync_point_manager_.get(); }
@@ -142,6 +147,7 @@ class GpuChannelManager : public IPC::Listener,
scoped_refptr<gfx::GLShareGroup> share_group_;
scoped_refptr<gpu::gles2::MailboxManager> mailbox_manager_;
GpuMemoryManager gpu_memory_manager_;
+ GpuEventsDispatcher gpu_devtools_events_dispatcher_;
GpuWatchdog* watchdog_;
scoped_refptr<SyncPointManager> sync_point_manager_;
scoped_ptr<gpu::gles2::ProgramCache> program_cache_;
diff --git a/content/common/gpu/gpu_command_buffer_stub.cc b/content/common/gpu/gpu_command_buffer_stub.cc
index 6749fad..1bcfbe8 100644
--- a/content/common/gpu/gpu_command_buffer_stub.cc
+++ b/content/common/gpu/gpu_command_buffer_stub.cc
@@ -10,6 +10,7 @@
#include "base/memory/shared_memory.h"
#include "base/time/time.h"
#include "build/build_config.h"
+#include "content/common/gpu/devtools_gpu_instrumentation.h"
#include "content/common/gpu/gpu_channel.h"
#include "content/common/gpu/gpu_channel_manager.h"
#include "content/common/gpu/gpu_command_buffer_stub.h"
@@ -169,6 +170,7 @@ GpuMemoryManager* GpuCommandBufferStub::GetMemoryManager() {
}
bool GpuCommandBufferStub::OnMessageReceived(const IPC::Message& message) {
+ devtools_gpu_instrumentation::ScopedGpuTask task(channel());
FastSetActiveURL(active_url_, active_url_hash_);
// Ensure the appropriate GL context is current before handling any IPC
diff --git a/content/common/gpu/gpu_messages.h b/content/common/gpu/gpu_messages.h
index cc8f794..08821bc 100644
--- a/content/common/gpu/gpu_messages.h
+++ b/content/common/gpu/gpu_messages.h
@@ -494,6 +494,14 @@ IPC_SYNC_MESSAGE_CONTROL1_1(GpuChannelMsg_CollectRenderingStatsForSurface,
int32 /* surface_id */,
content::GpuRenderingStats /* stats */)
+// Sent by DevTools agent in the inspected renderer process to initiate GPU
+// instrumentation events recording.
+IPC_SYNC_MESSAGE_CONTROL0_1(GpuChannelMsg_DevToolsStartEventsRecording,
+ int32 /* route_id */)
+
+// The message is sent when DevTools want to stop events recording.
+IPC_MESSAGE_CONTROL0(GpuChannelMsg_DevToolsStopEventsRecording)
+
#if defined(OS_ANDROID)
//------------------------------------------------------------------------------
// Stream Texture Messages