diff options
author | alph@chromium.org <alph@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-21 06:01:36 +0000 |
---|---|---|
committer | alph@chromium.org <alph@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-21 06:01:36 +0000 |
commit | 2bb3b8e022870b6ae42abed5d8a921b6b08f1c8c (patch) | |
tree | 60a746b3099b1f220eccc9979d7bd1bbfdf8111e /content/common | |
parent | e2693eab682106cfcfae8c767db5d3050804ec50 (diff) | |
download | chromium_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.h | 12 | ||||
-rw-r--r-- | content/common/gpu/client/gpu_channel_host.h | 2 | ||||
-rw-r--r-- | content/common/gpu/devtools_gpu_agent.cc | 78 | ||||
-rw-r--r-- | content/common/gpu/devtools_gpu_agent.h | 51 | ||||
-rw-r--r-- | content/common/gpu/devtools_gpu_instrumentation.cc | 50 | ||||
-rw-r--r-- | content/common/gpu/devtools_gpu_instrumentation.h | 65 | ||||
-rw-r--r-- | content/common/gpu/gpu_channel.cc | 15 | ||||
-rw-r--r-- | content/common/gpu/gpu_channel.h | 4 | ||||
-rw-r--r-- | content/common/gpu/gpu_channel_manager.h | 6 | ||||
-rw-r--r-- | content/common/gpu/gpu_command_buffer_stub.cc | 2 | ||||
-rw-r--r-- | content/common/gpu/gpu_messages.h | 8 |
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 |