blob: 1da6aecf2f3c82608fc57654592fc22c5d557c85 [file] [log] [blame]
[email protected]3bebb1f2012-01-05 23:14:071// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]7a31f7c2011-03-21 23:22:042// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]f24a1e2b2011-04-08 01:48:485#include "content/common/gpu/gpu_channel_manager.h"
[email protected]7a31f7c2011-03-21 23:22:046
[email protected]35a5b752011-11-17 23:58:587#include "base/bind.h"
[email protected]65dfc602012-07-23 20:39:398#include "base/command_line.h"
[email protected]2e7bbf22011-07-22 18:41:299#include "content/common/child_thread.h"
[email protected]1c982712011-06-27 23:44:3110#include "content/common/gpu/gpu_channel.h"
[email protected]672c7312012-02-03 16:28:5511#include "content/common/gpu/gpu_memory_manager.h"
[email protected]c9e2cbbb2012-05-12 21:17:2712#include "content/common/gpu/gpu_messages.h"
[email protected]c02f93e42012-06-05 23:35:1613#include "content/common/gpu/sync_point_manager.h"
[email protected]65dfc602012-07-23 20:39:3914#include "gpu/command_buffer/service/feature_info.h"
15#include "gpu/command_buffer/service/gpu_switches.h"
[email protected]18fd41952012-06-06 00:09:4616#include "gpu/command_buffer/service/mailbox_manager.h"
[email protected]65dfc602012-07-23 20:39:3917#include "gpu/command_buffer/service/memory_program_cache.h"
18#include "ui/gl/gl_bindings.h"
[email protected]c9e2cbbb2012-05-12 21:17:2719#include "ui/gl/gl_share_group.h"
[email protected]7a31f7c2011-03-21 23:22:0420
[email protected]2e7bbf22011-07-22 18:41:2921GpuChannelManager::GpuChannelManager(ChildThread* gpu_child_thread,
[email protected]2dcf7022011-04-15 19:20:4122 GpuWatchdog* watchdog,
[email protected]92bf9062011-05-02 18:00:4923 base::MessageLoopProxy* io_message_loop,
[email protected]f24a1e2b2011-04-08 01:48:4824 base::WaitableEvent* shutdown_event)
[email protected]35a5b752011-11-17 23:58:5825 : ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
[email protected]0fc35742011-04-13 17:57:5426 io_message_loop_(io_message_loop),
[email protected]7a31f7c2011-03-21 23:22:0427 shutdown_event_(shutdown_event),
[email protected]2e7bbf22011-07-22 18:41:2928 gpu_child_thread_(gpu_child_thread),
[email protected]672c7312012-02-03 16:28:5529 ALLOW_THIS_IN_INITIALIZER_LIST(gpu_memory_manager_(this,
30 GpuMemoryManager::kDefaultMaxSurfacesWithFrontbufferSoftLimit)),
[email protected]c02f93e42012-06-05 23:35:1631 watchdog_(watchdog),
[email protected]65dfc602012-07-23 20:39:3932 sync_point_manager_(new SyncPointManager),
33 program_cache_(NULL) {
[email protected]2e7bbf22011-07-22 18:41:2934 DCHECK(gpu_child_thread);
[email protected]7a31f7c2011-03-21 23:22:0435 DCHECK(io_message_loop);
36 DCHECK(shutdown_event);
37}
38
[email protected]f24a1e2b2011-04-08 01:48:4839GpuChannelManager::~GpuChannelManager() {
[email protected]7a31f7c2011-03-21 23:22:0440 gpu_channels_.clear();
[email protected]b8673e62012-09-25 03:15:0041 if (default_offscreen_surface_.get()) {
42 default_offscreen_surface_->Destroy();
43 default_offscreen_surface_ = NULL;
44 }
[email protected]7a31f7c2011-03-21 23:22:0445}
46
[email protected]65dfc602012-07-23 20:39:3947gpu::gles2::ProgramCache* GpuChannelManager::program_cache() {
48 if (!program_cache_.get() &&
49 (gfx::g_ARB_get_program_binary || gfx::g_OES_get_program_binary) &&
50 !CommandLine::ForCurrentProcess()->HasSwitch(
51 switches::kDisableGpuProgramCache)) {
52 program_cache_.reset(new gpu::gles2::MemoryProgramCache());
53 }
54 return program_cache_.get();
55}
56
[email protected]e608ce02012-01-12 22:30:0757void GpuChannelManager::RemoveChannel(int client_id) {
58 gpu_channels_.erase(client_id);
[email protected]7a31f7c2011-03-21 23:22:0459}
60
[email protected]2e7bbf22011-07-22 18:41:2961int GpuChannelManager::GenerateRouteID() {
62 static int last_id = 0;
63 return ++last_id;
64}
65
[email protected]d84effeb2012-06-25 17:03:1066void GpuChannelManager::AddRoute(int32 routing_id, IPC::Listener* listener) {
[email protected]2e7bbf22011-07-22 18:41:2967 gpu_child_thread_->AddRoute(routing_id, listener);
68}
69
70void GpuChannelManager::RemoveRoute(int32 routing_id) {
71 gpu_child_thread_->RemoveRoute(routing_id);
72}
73
[email protected]e608ce02012-01-12 22:30:0774GpuChannel* GpuChannelManager::LookupChannel(int32 client_id) {
75 GpuChannelMap::const_iterator iter = gpu_channels_.find(client_id);
[email protected]538195f2011-09-08 15:03:2076 if (iter == gpu_channels_.end())
77 return NULL;
78 else
79 return iter->second;
80}
81
[email protected]672c7312012-02-03 16:28:5582void GpuChannelManager::AppendAllCommandBufferStubs(
83 std::vector<GpuCommandBufferStubBase*>& stubs) {
84 for (GpuChannelMap::const_iterator it = gpu_channels_.begin();
85 it != gpu_channels_.end(); ++it ) {
86 it->second->AppendAllCommandBufferStubs(stubs);
87 }
[email protected]672c7312012-02-03 16:28:5588}
89
[email protected]f24a1e2b2011-04-08 01:48:4890bool GpuChannelManager::OnMessageReceived(const IPC::Message& msg) {
[email protected]7a31f7c2011-03-21 23:22:0491 bool msg_is_ok = true;
92 bool handled = true;
[email protected]f24a1e2b2011-04-08 01:48:4893 IPC_BEGIN_MESSAGE_MAP_EX(GpuChannelManager, msg, msg_is_ok)
[email protected]7a31f7c2011-03-21 23:22:0494 IPC_MESSAGE_HANDLER(GpuMsg_EstablishChannel, OnEstablishChannel)
95 IPC_MESSAGE_HANDLER(GpuMsg_CloseChannel, OnCloseChannel)
96 IPC_MESSAGE_HANDLER(GpuMsg_CreateViewCommandBuffer,
[email protected]8dc7fbd2011-04-15 00:13:1297 OnCreateViewCommandBuffer)
[email protected]7a31f7c2011-03-21 23:22:0498 IPC_MESSAGE_UNHANDLED(handled = false)
99 IPC_END_MESSAGE_MAP_EX()
100 return handled;
101}
102
[email protected]f24a1e2b2011-04-08 01:48:48103bool GpuChannelManager::Send(IPC::Message* msg) {
[email protected]2e7bbf22011-07-22 18:41:29104 return gpu_child_thread_->Send(msg);
[email protected]7a31f7c2011-03-21 23:22:04105}
106
[email protected]d8d97c22012-03-08 01:31:28107void GpuChannelManager::OnEstablishChannel(int client_id, bool share_context) {
[email protected]7a31f7c2011-03-21 23:22:04108 IPC::ChannelHandle channel_handle;
[email protected]7a31f7c2011-03-21 23:22:04109
[email protected]e608ce02012-01-12 22:30:07110 gfx::GLShareGroup* share_group = NULL;
[email protected]18fd41952012-06-06 00:09:46111 gpu::gles2::MailboxManager* mailbox_manager = NULL;
[email protected]d8d97c22012-03-08 01:31:28112 if (share_context) {
[email protected]18fd41952012-06-06 00:09:46113 if (!share_group_) {
[email protected]d8d97c22012-03-08 01:31:28114 share_group_ = new gfx::GLShareGroup;
[email protected]18fd41952012-06-06 00:09:46115 DCHECK(!mailbox_manager_);
116 mailbox_manager_ = new gpu::gles2::MailboxManager;
117 }
[email protected]d8d97c22012-03-08 01:31:28118 share_group = share_group_;
[email protected]18fd41952012-06-06 00:09:46119 mailbox_manager = mailbox_manager_;
[email protected]e608ce02012-01-12 22:30:07120 }
121
[email protected]3bebb1f2012-01-05 23:14:07122 scoped_refptr<GpuChannel> channel = new GpuChannel(this,
123 watchdog_,
[email protected]e608ce02012-01-12 22:30:07124 share_group,
[email protected]18fd41952012-06-06 00:09:46125 mailbox_manager,
[email protected]e608ce02012-01-12 22:30:07126 client_id,
[email protected]7f1a51c322012-07-19 18:52:02127 false);
[email protected]3bebb1f2012-01-05 23:14:07128 if (channel->Init(io_message_loop_, shutdown_event_)) {
[email protected]e608ce02012-01-12 22:30:07129 gpu_channels_[client_id] = channel;
[email protected]7a31f7c2011-03-21 23:22:04130 channel_handle.name = channel->GetChannelName();
[email protected]3bebb1f2012-01-05 23:14:07131
[email protected]7a31f7c2011-03-21 23:22:04132#if defined(OS_POSIX)
133 // On POSIX, pass the renderer-side FD. Also mark it as auto-close so
134 // that it gets closed after it has been sent.
[email protected]2ce26c432011-09-19 17:08:12135 int renderer_fd = channel->TakeRendererFileDescriptor();
[email protected]8bc550e2012-02-07 11:05:56136 DCHECK_NE(-1, renderer_fd);
[email protected]2ce26c432011-09-19 17:08:12137 channel_handle.socket = base::FileDescriptor(renderer_fd, true);
[email protected]7a31f7c2011-03-21 23:22:04138#endif
139 }
140
141 Send(new GpuHostMsg_ChannelEstablished(channel_handle));
142}
143
[email protected]f24a1e2b2011-04-08 01:48:48144void GpuChannelManager::OnCloseChannel(
145 const IPC::ChannelHandle& channel_handle) {
[email protected]7a31f7c2011-03-21 23:22:04146 for (GpuChannelMap::iterator iter = gpu_channels_.begin();
147 iter != gpu_channels_.end(); ++iter) {
148 if (iter->second->GetChannelName() == channel_handle.name) {
149 gpu_channels_.erase(iter);
150 return;
151 }
152 }
153}
154
[email protected]f24a1e2b2011-04-08 01:48:48155void GpuChannelManager::OnCreateViewCommandBuffer(
[email protected]fc4ed092012-02-21 19:46:55156 const gfx::GLSurfaceHandle& window,
[email protected]9f4f3322012-01-18 22:29:56157 int32 surface_id,
[email protected]e608ce02012-01-12 22:30:07158 int32 client_id,
[email protected]7a31f7c2011-03-21 23:22:04159 const GPUCreateCommandBufferConfig& init_params) {
[email protected]9f4f3322012-01-18 22:29:56160 DCHECK(surface_id);
[email protected]7a31f7c2011-03-21 23:22:04161 int32 route_id = MSG_ROUTING_NONE;
162
[email protected]e608ce02012-01-12 22:30:07163 GpuChannelMap::const_iterator iter = gpu_channels_.find(client_id);
[email protected]7a31f7c2011-03-21 23:22:04164 if (iter != gpu_channels_.end()) {
165 iter->second->CreateViewCommandBuffer(
[email protected]9f4f3322012-01-18 22:29:56166 window, surface_id, init_params, &route_id);
[email protected]7a31f7c2011-03-21 23:22:04167 }
168
169 Send(new GpuHostMsg_CommandBufferCreated(route_id));
170}
171
[email protected]0fc35742011-04-13 17:57:54172void GpuChannelManager::LoseAllContexts() {
173 MessageLoop::current()->PostTask(
[email protected]35a5b752011-11-17 23:58:58174 FROM_HERE,
175 base::Bind(&GpuChannelManager::OnLoseAllContexts,
176 weak_factory_.GetWeakPtr()));
[email protected]0fc35742011-04-13 17:57:54177}
178
179void GpuChannelManager::OnLoseAllContexts() {
180 gpu_channels_.clear();
181}
[email protected]b8673e62012-09-25 03:15:00182
183gfx::GLSurface* GpuChannelManager::GetDefaultOffscreenSurface() {
184 if (!default_offscreen_surface_.get()) {
185 default_offscreen_surface_ = gfx::GLSurface::CreateOffscreenGLSurface(
186 false, gfx::Size(1, 1));
187 }
188 return default_offscreen_surface_.get();
189}