base/threading: remove ScopedTracker placed for experiments
[chromium-blink-merge.git] / content / common / gpu / gpu_channel_manager.cc
blob040deb92beff8b5c7ebf986118d383d6d673dda1
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/common/gpu/gpu_channel_manager.h"
7 #include "base/bind.h"
8 #include "base/command_line.h"
9 #include "base/location.h"
10 #include "base/single_thread_task_runner.h"
11 #include "base/thread_task_runner_handle.h"
12 #include "content/common/gpu/gpu_channel.h"
13 #include "content/common/gpu/gpu_memory_buffer_factory.h"
14 #include "content/common/gpu/gpu_memory_manager.h"
15 #include "content/common/gpu/gpu_messages.h"
16 #include "content/common/message_router.h"
17 #include "gpu/command_buffer/common/value_state.h"
18 #include "gpu/command_buffer/service/feature_info.h"
19 #include "gpu/command_buffer/service/gpu_switches.h"
20 #include "gpu/command_buffer/service/mailbox_manager.h"
21 #include "gpu/command_buffer/service/memory_program_cache.h"
22 #include "gpu/command_buffer/service/shader_translator_cache.h"
23 #include "gpu/command_buffer/service/sync_point_manager.h"
24 #include "ipc/message_filter.h"
25 #include "ui/gl/gl_bindings.h"
26 #include "ui/gl/gl_share_group.h"
28 namespace content {
30 GpuChannelManager::GpuChannelManager(
31 MessageRouter* router,
32 GpuWatchdog* watchdog,
33 base::SingleThreadTaskRunner* io_task_runner,
34 base::WaitableEvent* shutdown_event,
35 IPC::SyncChannel* channel,
36 IPC::AttachmentBroker* broker,
37 gpu::SyncPointManager* sync_point_manager,
38 GpuMemoryBufferFactory* gpu_memory_buffer_factory)
39 : io_task_runner_(io_task_runner),
40 shutdown_event_(shutdown_event),
41 router_(router),
42 gpu_memory_manager_(
43 this,
44 GpuMemoryManager::kDefaultMaxSurfacesWithFrontbufferSoftLimit),
45 watchdog_(watchdog),
46 sync_point_manager_(sync_point_manager),
47 gpu_memory_buffer_factory_(gpu_memory_buffer_factory),
48 channel_(channel),
49 attachment_broker_(broker),
50 weak_factory_(this) {
51 DCHECK(router_);
52 DCHECK(io_task_runner);
53 DCHECK(shutdown_event);
56 GpuChannelManager::~GpuChannelManager() {
57 gpu_channels_.clear();
58 if (default_offscreen_surface_.get()) {
59 default_offscreen_surface_->Destroy();
60 default_offscreen_surface_ = NULL;
64 gpu::gles2::ProgramCache* GpuChannelManager::program_cache() {
65 if (!program_cache_.get() &&
66 (gfx::g_driver_gl.ext.b_GL_ARB_get_program_binary ||
67 gfx::g_driver_gl.ext.b_GL_OES_get_program_binary) &&
68 !base::CommandLine::ForCurrentProcess()->HasSwitch(
69 switches::kDisableGpuProgramCache)) {
70 program_cache_.reset(new gpu::gles2::MemoryProgramCache());
72 return program_cache_.get();
75 gpu::gles2::ShaderTranslatorCache*
76 GpuChannelManager::shader_translator_cache() {
77 if (!shader_translator_cache_.get())
78 shader_translator_cache_ = new gpu::gles2::ShaderTranslatorCache;
79 return shader_translator_cache_.get();
82 void GpuChannelManager::RemoveChannel(int client_id) {
83 Send(new GpuHostMsg_DestroyChannel(client_id));
84 gpu_channels_.erase(client_id);
87 int GpuChannelManager::GenerateRouteID() {
88 static int last_id = 0;
89 return ++last_id;
92 void GpuChannelManager::AddRoute(int32 routing_id, IPC::Listener* listener) {
93 router_->AddRoute(routing_id, listener);
96 void GpuChannelManager::RemoveRoute(int32 routing_id) {
97 router_->RemoveRoute(routing_id);
100 GpuChannel* GpuChannelManager::LookupChannel(int32 client_id) {
101 GpuChannelMap::const_iterator iter = gpu_channels_.find(client_id);
102 if (iter == gpu_channels_.end())
103 return NULL;
104 else
105 return iter->second;
108 bool GpuChannelManager::OnMessageReceived(const IPC::Message& msg) {
109 bool handled = true;
110 IPC_BEGIN_MESSAGE_MAP(GpuChannelManager, msg)
111 IPC_MESSAGE_HANDLER(GpuMsg_EstablishChannel, OnEstablishChannel)
112 IPC_MESSAGE_HANDLER(GpuMsg_CloseChannel, OnCloseChannel)
113 IPC_MESSAGE_HANDLER(GpuMsg_CreateViewCommandBuffer,
114 OnCreateViewCommandBuffer)
115 IPC_MESSAGE_HANDLER(GpuMsg_DestroyGpuMemoryBuffer, OnDestroyGpuMemoryBuffer)
116 IPC_MESSAGE_HANDLER(GpuMsg_LoadedShader, OnLoadedShader)
117 IPC_MESSAGE_HANDLER(GpuMsg_Finalize, OnFinalize)
118 IPC_MESSAGE_HANDLER(GpuMsg_UpdateValueState, OnUpdateValueState)
119 IPC_MESSAGE_UNHANDLED(handled = false)
120 IPC_END_MESSAGE_MAP()
121 return handled;
124 bool GpuChannelManager::Send(IPC::Message* msg) { return router_->Send(msg); }
126 void GpuChannelManager::OnEstablishChannel(int client_id,
127 uint64_t client_tracing_id,
128 bool share_context,
129 bool allow_future_sync_points) {
130 IPC::ChannelHandle channel_handle;
132 gfx::GLShareGroup* share_group = NULL;
133 gpu::gles2::MailboxManager* mailbox_manager = NULL;
134 if (share_context) {
135 if (!share_group_.get()) {
136 share_group_ = new gfx::GLShareGroup;
137 DCHECK(!mailbox_manager_.get());
138 mailbox_manager_ = gpu::gles2::MailboxManager::Create();
140 share_group = share_group_.get();
141 mailbox_manager = mailbox_manager_.get();
144 scoped_ptr<GpuChannel> channel(new GpuChannel(this,
145 watchdog_,
146 share_group,
147 mailbox_manager,
148 client_id,
149 client_tracing_id,
150 false,
151 allow_future_sync_points));
152 channel->Init(io_task_runner_.get(), shutdown_event_, attachment_broker_);
153 channel_handle.name = channel->GetChannelName();
155 #if defined(OS_POSIX)
156 // On POSIX, pass the renderer-side FD. Also mark it as auto-close so
157 // that it gets closed after it has been sent.
158 base::ScopedFD renderer_fd = channel->TakeRendererFileDescriptor();
159 DCHECK(renderer_fd.is_valid());
160 channel_handle.socket = base::FileDescriptor(renderer_fd.Pass());
161 #endif
163 gpu_channels_.set(client_id, channel.Pass());
165 Send(new GpuHostMsg_ChannelEstablished(channel_handle));
168 void GpuChannelManager::OnCloseChannel(
169 const IPC::ChannelHandle& channel_handle) {
170 for (GpuChannelMap::iterator iter = gpu_channels_.begin();
171 iter != gpu_channels_.end(); ++iter) {
172 if (iter->second->GetChannelName() == channel_handle.name) {
173 gpu_channels_.erase(iter);
174 return;
179 void GpuChannelManager::OnCreateViewCommandBuffer(
180 const gfx::GLSurfaceHandle& window,
181 int32 surface_id,
182 int32 client_id,
183 const GPUCreateCommandBufferConfig& init_params,
184 int32 route_id) {
185 DCHECK(surface_id);
186 CreateCommandBufferResult result = CREATE_COMMAND_BUFFER_FAILED;
188 GpuChannelMap::const_iterator iter = gpu_channels_.find(client_id);
189 if (iter != gpu_channels_.end()) {
190 result = iter->second->CreateViewCommandBuffer(
191 window, surface_id, init_params, route_id);
194 Send(new GpuHostMsg_CommandBufferCreated(result));
197 void GpuChannelManager::DestroyGpuMemoryBuffer(
198 gfx::GpuMemoryBufferId id,
199 int client_id) {
200 io_task_runner_->PostTask(
201 FROM_HERE, base::Bind(&GpuChannelManager::DestroyGpuMemoryBufferOnIO,
202 base::Unretained(this), id, client_id));
205 void GpuChannelManager::DestroyGpuMemoryBufferOnIO(
206 gfx::GpuMemoryBufferId id,
207 int client_id) {
208 gpu_memory_buffer_factory_->DestroyGpuMemoryBuffer(id, client_id);
211 void GpuChannelManager::OnDestroyGpuMemoryBuffer(
212 gfx::GpuMemoryBufferId id,
213 int client_id,
214 int32 sync_point) {
215 if (!sync_point) {
216 DestroyGpuMemoryBuffer(id, client_id);
217 } else {
218 sync_point_manager()->AddSyncPointCallback(
219 sync_point,
220 base::Bind(&GpuChannelManager::DestroyGpuMemoryBuffer,
221 base::Unretained(this),
223 client_id));
227 void GpuChannelManager::OnUpdateValueState(
228 int client_id, unsigned int target, const gpu::ValueState& state) {
229 // Only pass updated state to the channel corresponding to the
230 // render_widget_host where the event originated.
231 GpuChannelMap::const_iterator iter = gpu_channels_.find(client_id);
232 if (iter != gpu_channels_.end()) {
233 iter->second->HandleUpdateValueState(target, state);
237 void GpuChannelManager::OnLoadedShader(std::string program_proto) {
238 if (program_cache())
239 program_cache()->LoadProgram(program_proto);
242 bool GpuChannelManager::HandleMessagesScheduled() {
243 for (GpuChannelMap::iterator iter = gpu_channels_.begin();
244 iter != gpu_channels_.end(); ++iter) {
245 if (iter->second->handle_messages_scheduled())
246 return true;
248 return false;
251 uint64 GpuChannelManager::MessagesProcessed() {
252 uint64 messages_processed = 0;
254 for (GpuChannelMap::iterator iter = gpu_channels_.begin();
255 iter != gpu_channels_.end(); ++iter) {
256 messages_processed += iter->second->messages_processed();
258 return messages_processed;
261 void GpuChannelManager::LoseAllContexts() {
262 for (GpuChannelMap::iterator iter = gpu_channels_.begin();
263 iter != gpu_channels_.end(); ++iter) {
264 iter->second->MarkAllContextsLost();
266 base::ThreadTaskRunnerHandle::Get()->PostTask(
267 FROM_HERE, base::Bind(&GpuChannelManager::OnLoseAllContexts,
268 weak_factory_.GetWeakPtr()));
271 void GpuChannelManager::OnLoseAllContexts() {
272 gpu_channels_.clear();
275 gfx::GLSurface* GpuChannelManager::GetDefaultOffscreenSurface() {
276 if (!default_offscreen_surface_.get()) {
277 default_offscreen_surface_ =
278 gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size());
280 return default_offscreen_surface_.get();
283 void GpuChannelManager::OnFinalize() {
284 // Quit the GPU process
285 base::MessageLoop::current()->Quit();
288 } // namespace content