Apply _RELATIVE relocations ahead of others.
[chromium-blink-merge.git] / content / common / gpu / gpu_channel_manager.cc
bloba073e20151edce4dc033a6d9e54bf3c0196b214a
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 "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"
24 namespace content {
26 namespace {
28 class GpuChannelManagerMessageFilter : public IPC::MessageFilter {
29 public:
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 {
35 DCHECK(!sender_);
36 sender_ = sender;
39 void OnFilterRemoved() override {
40 DCHECK(sender_);
41 sender_ = NULL;
44 bool OnMessageReceived(const IPC::Message& message) override {
45 DCHECK(sender_);
46 bool handled = true;
47 IPC_BEGIN_MESSAGE_MAP(GpuChannelManagerMessageFilter, message)
48 IPC_MESSAGE_HANDLER(GpuMsg_CreateGpuMemoryBuffer, OnCreateGpuMemoryBuffer)
49 IPC_MESSAGE_UNHANDLED(handled = false)
50 IPC_END_MESSAGE_MAP()
51 return handled;
54 protected:
55 ~GpuChannelManagerMessageFilter() override {}
57 void OnCreateGpuMemoryBuffer(
58 const GpuMsg_CreateGpuMemoryBuffer_Params& params) {
59 TRACE_EVENT2("gpu",
60 "GpuChannelManagerMessageFilter::OnCreateGpuMemoryBuffer",
61 "id",
62 params.id,
63 "client_id",
64 params.client_id);
65 sender_->Send(new GpuHostMsg_GpuMemoryBufferCreated(
66 gpu_memory_buffer_factory_->CreateGpuMemoryBuffer(params.type,
67 params.id,
68 params.size,
69 params.format,
70 params.usage,
71 params.client_id)));
74 IPC::Sender* sender_;
75 GpuMemoryBufferFactory* gpu_memory_buffer_factory_;
78 } // namespace
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),
87 router_(router),
88 gpu_memory_manager_(
89 this,
90 GpuMemoryManager::kDefaultMaxSurfacesWithFrontbufferSoftLimit),
91 watchdog_(watchdog),
92 sync_point_manager_(new SyncPointManager),
93 gpu_memory_buffer_factory_(GpuMemoryBufferFactory::Create()),
94 channel_(channel),
95 filter_(new GpuChannelManagerMessageFilter(
96 gpu_memory_buffer_factory_.get())),
97 weak_factory_(this) {
98 DCHECK(router_);
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;
137 return ++last_id;
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())
151 return NULL;
152 else
153 return iter->second;
156 bool GpuChannelManager::OnMessageReceived(const IPC::Message& msg) {
157 bool handled = true;
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()
167 return handled;
170 bool GpuChannelManager::Send(IPC::Message* msg) { return router_->Send(msg); }
172 void GpuChannelManager::OnEstablishChannel(int client_id,
173 bool share_context,
174 bool allow_future_sync_points) {
175 IPC::ChannelHandle channel_handle;
177 gfx::GLShareGroup* share_group = NULL;
178 gpu::gles2::MailboxManager* mailbox_manager = NULL;
179 if (share_context) {
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,
190 watchdog_,
191 share_group,
192 mailbox_manager,
193 client_id,
194 false,
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());
205 #endif
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);
218 return;
223 void GpuChannelManager::OnCreateViewCommandBuffer(
224 const gfx::GLSurfaceHandle& window,
225 int32 surface_id,
226 int32 client_id,
227 const GPUCreateCommandBufferConfig& init_params,
228 int32 route_id) {
229 DCHECK(surface_id);
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,
244 int client_id) {
245 io_message_loop_->PostTask(
246 FROM_HERE,
247 base::Bind(&GpuChannelManager::DestroyGpuMemoryBufferOnIO,
248 base::Unretained(this),
249 type,
251 client_id));
254 void GpuChannelManager::DestroyGpuMemoryBufferOnIO(
255 gfx::GpuMemoryBufferType type,
256 gfx::GpuMemoryBufferId id,
257 int client_id) {
258 gpu_memory_buffer_factory_->DestroyGpuMemoryBuffer(type, id, client_id);
261 void GpuChannelManager::OnDestroyGpuMemoryBuffer(
262 gfx::GpuMemoryBufferType type,
263 gfx::GpuMemoryBufferId id,
264 int client_id,
265 int32 sync_point) {
266 if (!sync_point) {
267 DestroyGpuMemoryBuffer(type, id, client_id);
268 } else {
269 sync_point_manager()->AddSyncPointCallback(
270 sync_point,
271 base::Bind(&GpuChannelManager::DestroyGpuMemoryBuffer,
272 base::Unretained(this),
273 type,
275 client_id));
279 void GpuChannelManager::OnLoadedShader(std::string program_proto) {
280 if (program_cache())
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())
288 return true;
290 return false;
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(
309 FROM_HERE,
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