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"
8 #include "base/command_line.h"
9 #include "content/common/gpu/gpu_channel.h"
10 #include "content/common/gpu/gpu_memory_buffer_factory.h"
11 #include "content/common/gpu/gpu_memory_manager.h"
12 #include "content/common/gpu/gpu_messages.h"
13 #include "content/common/gpu/sync_point_manager.h"
14 #include "content/common/message_router.h"
15 #include "gpu/command_buffer/service/feature_info.h"
16 #include "gpu/command_buffer/service/gpu_switches.h"
17 #include "gpu/command_buffer/service/mailbox_manager_impl.h"
18 #include "gpu/command_buffer/service/memory_program_cache.h"
19 #include "gpu/command_buffer/service/shader_translator_cache.h"
20 #include "ipc/message_filter.h"
21 #include "ui/gl/gl_bindings.h"
22 #include "ui/gl/gl_share_group.h"
28 class GpuChannelManagerMessageFilter
: public IPC::MessageFilter
{
30 GpuChannelManagerMessageFilter(
31 GpuMemoryBufferFactory
* gpu_memory_buffer_factory
)
32 : sender_(NULL
), gpu_memory_buffer_factory_(gpu_memory_buffer_factory
) {}
34 void OnFilterAdded(IPC::Sender
* sender
) override
{
39 void OnFilterRemoved() override
{
44 bool OnMessageReceived(const IPC::Message
& message
) override
{
47 IPC_BEGIN_MESSAGE_MAP(GpuChannelManagerMessageFilter
, message
)
48 IPC_MESSAGE_HANDLER(GpuMsg_CreateGpuMemoryBuffer
, OnCreateGpuMemoryBuffer
)
49 IPC_MESSAGE_UNHANDLED(handled
= false)
55 ~GpuChannelManagerMessageFilter() override
{}
57 void OnCreateGpuMemoryBuffer(
58 const GpuMsg_CreateGpuMemoryBuffer_Params
& params
) {
60 "GpuChannelManagerMessageFilter::OnCreateGpuMemoryBuffer",
65 sender_
->Send(new GpuHostMsg_GpuMemoryBufferCreated(
66 gpu_memory_buffer_factory_
->CreateGpuMemoryBuffer(params
.type
,
75 GpuMemoryBufferFactory
* gpu_memory_buffer_factory_
;
80 GpuChannelManager::GpuChannelManager(MessageRouter
* router
,
81 GpuWatchdog
* watchdog
,
82 base::MessageLoopProxy
* io_message_loop
,
83 base::WaitableEvent
* shutdown_event
,
84 IPC::SyncChannel
* channel
)
85 : io_message_loop_(io_message_loop
),
86 shutdown_event_(shutdown_event
),
90 GpuMemoryManager::kDefaultMaxSurfacesWithFrontbufferSoftLimit
),
92 sync_point_manager_(new SyncPointManager
),
93 gpu_memory_buffer_factory_(GpuMemoryBufferFactory::Create()),
95 filter_(new GpuChannelManagerMessageFilter(
96 gpu_memory_buffer_factory_
.get())),
99 DCHECK(io_message_loop
);
100 DCHECK(shutdown_event
);
101 channel_
->AddFilter(filter_
.get());
104 GpuChannelManager::~GpuChannelManager() {
105 gpu_channels_
.clear();
106 if (default_offscreen_surface_
.get()) {
107 default_offscreen_surface_
->Destroy();
108 default_offscreen_surface_
= NULL
;
112 gpu::gles2::ProgramCache
* GpuChannelManager::program_cache() {
113 if (!program_cache_
.get() &&
114 (gfx::g_driver_gl
.ext
.b_GL_ARB_get_program_binary
||
115 gfx::g_driver_gl
.ext
.b_GL_OES_get_program_binary
) &&
116 !CommandLine::ForCurrentProcess()->HasSwitch(
117 switches::kDisableGpuProgramCache
)) {
118 program_cache_
.reset(new gpu::gles2::MemoryProgramCache());
120 return program_cache_
.get();
123 gpu::gles2::ShaderTranslatorCache
*
124 GpuChannelManager::shader_translator_cache() {
125 if (!shader_translator_cache_
.get())
126 shader_translator_cache_
= new gpu::gles2::ShaderTranslatorCache
;
127 return shader_translator_cache_
.get();
130 void GpuChannelManager::RemoveChannel(int client_id
) {
131 Send(new GpuHostMsg_DestroyChannel(client_id
));
132 gpu_channels_
.erase(client_id
);
135 int GpuChannelManager::GenerateRouteID() {
136 static int last_id
= 0;
140 void GpuChannelManager::AddRoute(int32 routing_id
, IPC::Listener
* listener
) {
141 router_
->AddRoute(routing_id
, listener
);
144 void GpuChannelManager::RemoveRoute(int32 routing_id
) {
145 router_
->RemoveRoute(routing_id
);
148 GpuChannel
* GpuChannelManager::LookupChannel(int32 client_id
) {
149 GpuChannelMap::const_iterator iter
= gpu_channels_
.find(client_id
);
150 if (iter
== gpu_channels_
.end())
156 bool GpuChannelManager::OnMessageReceived(const IPC::Message
& msg
) {
158 IPC_BEGIN_MESSAGE_MAP(GpuChannelManager
, msg
)
159 IPC_MESSAGE_HANDLER(GpuMsg_EstablishChannel
, OnEstablishChannel
)
160 IPC_MESSAGE_HANDLER(GpuMsg_CloseChannel
, OnCloseChannel
)
161 IPC_MESSAGE_HANDLER(GpuMsg_CreateViewCommandBuffer
,
162 OnCreateViewCommandBuffer
)
163 IPC_MESSAGE_HANDLER(GpuMsg_DestroyGpuMemoryBuffer
, OnDestroyGpuMemoryBuffer
)
164 IPC_MESSAGE_HANDLER(GpuMsg_LoadedShader
, OnLoadedShader
)
165 IPC_MESSAGE_UNHANDLED(handled
= false)
166 IPC_END_MESSAGE_MAP()
170 bool GpuChannelManager::Send(IPC::Message
* msg
) { return router_
->Send(msg
); }
172 void GpuChannelManager::OnEstablishChannel(int client_id
,
174 bool allow_future_sync_points
) {
175 IPC::ChannelHandle channel_handle
;
177 gfx::GLShareGroup
* share_group
= NULL
;
178 gpu::gles2::MailboxManager
* mailbox_manager
= NULL
;
180 if (!share_group_
.get()) {
181 share_group_
= new gfx::GLShareGroup
;
182 DCHECK(!mailbox_manager_
.get());
183 mailbox_manager_
= new gpu::gles2::MailboxManagerImpl
;
185 share_group
= share_group_
.get();
186 mailbox_manager
= mailbox_manager_
.get();
189 scoped_ptr
<GpuChannel
> channel(new GpuChannel(this,
195 allow_future_sync_points
));
196 channel
->Init(io_message_loop_
.get(), shutdown_event_
);
197 channel_handle
.name
= channel
->GetChannelName();
199 #if defined(OS_POSIX)
200 // On POSIX, pass the renderer-side FD. Also mark it as auto-close so
201 // that it gets closed after it has been sent.
202 base::ScopedFD renderer_fd
= channel
->TakeRendererFileDescriptor();
203 DCHECK(renderer_fd
.is_valid());
204 channel_handle
.socket
= base::FileDescriptor(renderer_fd
.Pass());
207 gpu_channels_
.set(client_id
, channel
.Pass());
209 Send(new GpuHostMsg_ChannelEstablished(channel_handle
));
212 void GpuChannelManager::OnCloseChannel(
213 const IPC::ChannelHandle
& channel_handle
) {
214 for (GpuChannelMap::iterator iter
= gpu_channels_
.begin();
215 iter
!= gpu_channels_
.end(); ++iter
) {
216 if (iter
->second
->GetChannelName() == channel_handle
.name
) {
217 gpu_channels_
.erase(iter
);
223 void GpuChannelManager::OnCreateViewCommandBuffer(
224 const gfx::GLSurfaceHandle
& window
,
227 const GPUCreateCommandBufferConfig
& init_params
,
230 CreateCommandBufferResult result
= CREATE_COMMAND_BUFFER_FAILED
;
232 GpuChannelMap::const_iterator iter
= gpu_channels_
.find(client_id
);
233 if (iter
!= gpu_channels_
.end()) {
234 result
= iter
->second
->CreateViewCommandBuffer(
235 window
, surface_id
, init_params
, route_id
);
238 Send(new GpuHostMsg_CommandBufferCreated(result
));
241 void GpuChannelManager::DestroyGpuMemoryBuffer(
242 gfx::GpuMemoryBufferType type
,
243 gfx::GpuMemoryBufferId id
,
245 io_message_loop_
->PostTask(
247 base::Bind(&GpuChannelManager::DestroyGpuMemoryBufferOnIO
,
248 base::Unretained(this),
254 void GpuChannelManager::DestroyGpuMemoryBufferOnIO(
255 gfx::GpuMemoryBufferType type
,
256 gfx::GpuMemoryBufferId id
,
258 gpu_memory_buffer_factory_
->DestroyGpuMemoryBuffer(type
, id
, client_id
);
261 void GpuChannelManager::OnDestroyGpuMemoryBuffer(
262 gfx::GpuMemoryBufferType type
,
263 gfx::GpuMemoryBufferId id
,
267 DestroyGpuMemoryBuffer(type
, id
, client_id
);
269 sync_point_manager()->AddSyncPointCallback(
271 base::Bind(&GpuChannelManager::DestroyGpuMemoryBuffer
,
272 base::Unretained(this),
279 void GpuChannelManager::OnLoadedShader(std::string program_proto
) {
281 program_cache()->LoadProgram(program_proto
);
284 bool GpuChannelManager::HandleMessagesScheduled() {
285 for (GpuChannelMap::iterator iter
= gpu_channels_
.begin();
286 iter
!= gpu_channels_
.end(); ++iter
) {
287 if (iter
->second
->handle_messages_scheduled())
293 uint64
GpuChannelManager::MessagesProcessed() {
294 uint64 messages_processed
= 0;
296 for (GpuChannelMap::iterator iter
= gpu_channels_
.begin();
297 iter
!= gpu_channels_
.end(); ++iter
) {
298 messages_processed
+= iter
->second
->messages_processed();
300 return messages_processed
;
303 void GpuChannelManager::LoseAllContexts() {
304 for (GpuChannelMap::iterator iter
= gpu_channels_
.begin();
305 iter
!= gpu_channels_
.end(); ++iter
) {
306 iter
->second
->MarkAllContextsLost();
308 base::MessageLoop::current()->PostTask(
310 base::Bind(&GpuChannelManager::OnLoseAllContexts
,
311 weak_factory_
.GetWeakPtr()));
314 void GpuChannelManager::OnLoseAllContexts() {
315 gpu_channels_
.clear();
318 gfx::GLSurface
* GpuChannelManager::GetDefaultOffscreenSurface() {
319 if (!default_offscreen_surface_
.get()) {
320 default_offscreen_surface_
=
321 gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size());
323 return default_offscreen_surface_
.get();
326 } // namespace content