Add P2PDatagramSocket and P2PStreamSocket interfaces.
[chromium-blink-merge.git] / content / common / gpu / gpu_channel_manager.cc
blobc8992dfdc9503511b0cba6eea34f3be7b3950bf8
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_gl_api_implementation.h"
27 #include "ui/gl/gl_share_group.h"
28 #if defined(USE_OZONE)
29 #include "ui/ozone/public/gpu_platform_support.h"
30 #include "ui/ozone/public/ozone_platform.h"
31 #endif
33 namespace content {
35 GpuChannelManager::GpuChannelManager(
36 MessageRouter* router,
37 GpuWatchdog* watchdog,
38 base::SingleThreadTaskRunner* io_task_runner,
39 base::WaitableEvent* shutdown_event,
40 IPC::SyncChannel* channel,
41 IPC::AttachmentBroker* broker,
42 GpuMemoryBufferFactory* gpu_memory_buffer_factory)
43 : io_task_runner_(io_task_runner),
44 shutdown_event_(shutdown_event),
45 router_(router),
46 gpu_memory_manager_(
47 this,
48 GpuMemoryManager::kDefaultMaxSurfacesWithFrontbufferSoftLimit),
49 watchdog_(watchdog),
50 sync_point_manager_(gpu::SyncPointManager::Create(false)),
51 gpu_memory_buffer_factory_(gpu_memory_buffer_factory),
52 channel_(channel),
53 relinquish_resources_pending_(false),
54 attachment_broker_(broker),
55 weak_factory_(this) {
56 DCHECK(router_);
57 DCHECK(io_task_runner);
58 DCHECK(shutdown_event);
61 GpuChannelManager::~GpuChannelManager() {
62 gpu_channels_.clear();
63 if (default_offscreen_surface_.get()) {
64 default_offscreen_surface_->Destroy();
65 default_offscreen_surface_ = NULL;
69 gpu::gles2::ProgramCache* GpuChannelManager::program_cache() {
70 if (!program_cache_.get() &&
71 (gfx::g_driver_gl.ext.b_GL_ARB_get_program_binary ||
72 gfx::g_driver_gl.ext.b_GL_OES_get_program_binary ||
73 gfx::GetGLVersionInfo()->is_es3) &&
74 !base::CommandLine::ForCurrentProcess()->HasSwitch(
75 switches::kDisableGpuProgramCache)) {
76 program_cache_.reset(new gpu::gles2::MemoryProgramCache());
78 return program_cache_.get();
81 gpu::gles2::ShaderTranslatorCache*
82 GpuChannelManager::shader_translator_cache() {
83 if (!shader_translator_cache_.get())
84 shader_translator_cache_ = new gpu::gles2::ShaderTranslatorCache;
85 return shader_translator_cache_.get();
88 void GpuChannelManager::RemoveChannel(int client_id) {
89 Send(new GpuHostMsg_DestroyChannel(client_id));
90 gpu_channels_.erase(client_id);
91 CheckRelinquishGpuResources();
94 int GpuChannelManager::GenerateRouteID() {
95 static int last_id = 0;
96 return ++last_id;
99 void GpuChannelManager::AddRoute(int32 routing_id, IPC::Listener* listener) {
100 router_->AddRoute(routing_id, listener);
103 void GpuChannelManager::RemoveRoute(int32 routing_id) {
104 router_->RemoveRoute(routing_id);
107 GpuChannel* GpuChannelManager::LookupChannel(int32 client_id) {
108 GpuChannelMap::const_iterator iter = gpu_channels_.find(client_id);
109 if (iter == gpu_channels_.end())
110 return NULL;
111 else
112 return iter->second;
115 bool GpuChannelManager::OnMessageReceived(const IPC::Message& msg) {
116 bool handled = true;
117 IPC_BEGIN_MESSAGE_MAP(GpuChannelManager, msg)
118 IPC_MESSAGE_HANDLER(GpuMsg_EstablishChannel, OnEstablishChannel)
119 IPC_MESSAGE_HANDLER(GpuMsg_CloseChannel, OnCloseChannel)
120 IPC_MESSAGE_HANDLER(GpuMsg_CreateViewCommandBuffer,
121 OnCreateViewCommandBuffer)
122 IPC_MESSAGE_HANDLER(GpuMsg_DestroyGpuMemoryBuffer, OnDestroyGpuMemoryBuffer)
123 IPC_MESSAGE_HANDLER(GpuMsg_LoadedShader, OnLoadedShader)
124 IPC_MESSAGE_HANDLER(GpuMsg_RelinquishResources, OnRelinquishResources)
125 IPC_MESSAGE_HANDLER(GpuMsg_UpdateValueState, OnUpdateValueState)
126 IPC_MESSAGE_UNHANDLED(handled = false)
127 IPC_END_MESSAGE_MAP()
128 return handled;
131 bool GpuChannelManager::Send(IPC::Message* msg) { return router_->Send(msg); }
133 void GpuChannelManager::OnEstablishChannel(int client_id,
134 bool share_context,
135 bool allow_future_sync_points) {
136 IPC::ChannelHandle channel_handle;
138 gfx::GLShareGroup* share_group = NULL;
139 gpu::gles2::MailboxManager* mailbox_manager = NULL;
140 if (share_context) {
141 if (!share_group_.get()) {
142 share_group_ = new gfx::GLShareGroup;
143 DCHECK(!mailbox_manager_.get());
144 mailbox_manager_ = gpu::gles2::MailboxManager::Create();
146 share_group = share_group_.get();
147 mailbox_manager = mailbox_manager_.get();
150 scoped_ptr<GpuChannel> channel(new GpuChannel(this,
151 watchdog_,
152 share_group,
153 mailbox_manager,
154 client_id,
155 false,
156 allow_future_sync_points));
157 channel->Init(io_task_runner_.get(), shutdown_event_, attachment_broker_);
158 channel_handle.name = channel->GetChannelName();
160 #if defined(OS_POSIX)
161 // On POSIX, pass the renderer-side FD. Also mark it as auto-close so
162 // that it gets closed after it has been sent.
163 base::ScopedFD renderer_fd = channel->TakeRendererFileDescriptor();
164 DCHECK(renderer_fd.is_valid());
165 channel_handle.socket = base::FileDescriptor(renderer_fd.Pass());
166 #endif
168 gpu_channels_.set(client_id, channel.Pass());
170 Send(new GpuHostMsg_ChannelEstablished(channel_handle));
173 void GpuChannelManager::OnCloseChannel(
174 const IPC::ChannelHandle& channel_handle) {
175 for (GpuChannelMap::iterator iter = gpu_channels_.begin();
176 iter != gpu_channels_.end(); ++iter) {
177 if (iter->second->GetChannelName() == channel_handle.name) {
178 gpu_channels_.erase(iter);
179 CheckRelinquishGpuResources();
180 return;
185 void GpuChannelManager::OnCreateViewCommandBuffer(
186 const gfx::GLSurfaceHandle& window,
187 int32 surface_id,
188 int32 client_id,
189 const GPUCreateCommandBufferConfig& init_params,
190 int32 route_id) {
191 DCHECK(surface_id);
192 CreateCommandBufferResult result = CREATE_COMMAND_BUFFER_FAILED;
194 GpuChannelMap::const_iterator iter = gpu_channels_.find(client_id);
195 if (iter != gpu_channels_.end()) {
196 result = iter->second->CreateViewCommandBuffer(
197 window, surface_id, init_params, route_id);
200 Send(new GpuHostMsg_CommandBufferCreated(result));
203 void GpuChannelManager::DestroyGpuMemoryBuffer(
204 gfx::GpuMemoryBufferId id,
205 int client_id) {
206 io_task_runner_->PostTask(
207 FROM_HERE, base::Bind(&GpuChannelManager::DestroyGpuMemoryBufferOnIO,
208 base::Unretained(this), id, client_id));
211 void GpuChannelManager::DestroyGpuMemoryBufferOnIO(
212 gfx::GpuMemoryBufferId id,
213 int client_id) {
214 gpu_memory_buffer_factory_->DestroyGpuMemoryBuffer(id, client_id);
217 void GpuChannelManager::OnDestroyGpuMemoryBuffer(
218 gfx::GpuMemoryBufferId id,
219 int client_id,
220 int32 sync_point) {
221 if (!sync_point) {
222 DestroyGpuMemoryBuffer(id, client_id);
223 } else {
224 sync_point_manager()->AddSyncPointCallback(
225 sync_point,
226 base::Bind(&GpuChannelManager::DestroyGpuMemoryBuffer,
227 base::Unretained(this),
229 client_id));
233 void GpuChannelManager::OnUpdateValueState(
234 int client_id, unsigned int target, const gpu::ValueState& state) {
235 // Only pass updated state to the channel corresponding to the
236 // render_widget_host where the event originated.
237 GpuChannelMap::const_iterator iter = gpu_channels_.find(client_id);
238 if (iter != gpu_channels_.end()) {
239 iter->second->HandleUpdateValueState(target, state);
243 void GpuChannelManager::OnLoadedShader(std::string program_proto) {
244 if (program_cache())
245 program_cache()->LoadProgram(program_proto);
248 bool GpuChannelManager::HandleMessagesScheduled() {
249 for (GpuChannelMap::iterator iter = gpu_channels_.begin();
250 iter != gpu_channels_.end(); ++iter) {
251 if (iter->second->handle_messages_scheduled())
252 return true;
254 return false;
257 uint64 GpuChannelManager::MessagesProcessed() {
258 uint64 messages_processed = 0;
260 for (GpuChannelMap::iterator iter = gpu_channels_.begin();
261 iter != gpu_channels_.end(); ++iter) {
262 messages_processed += iter->second->messages_processed();
264 return messages_processed;
267 void GpuChannelManager::LoseAllContexts() {
268 for (GpuChannelMap::iterator iter = gpu_channels_.begin();
269 iter != gpu_channels_.end(); ++iter) {
270 iter->second->MarkAllContextsLost();
272 base::ThreadTaskRunnerHandle::Get()->PostTask(
273 FROM_HERE, base::Bind(&GpuChannelManager::OnLoseAllContexts,
274 weak_factory_.GetWeakPtr()));
277 void GpuChannelManager::OnLoseAllContexts() {
278 gpu_channels_.clear();
279 CheckRelinquishGpuResources();
282 gfx::GLSurface* GpuChannelManager::GetDefaultOffscreenSurface() {
283 if (!default_offscreen_surface_.get()) {
284 default_offscreen_surface_ =
285 gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size());
287 return default_offscreen_surface_.get();
290 void GpuChannelManager::OnRelinquishResources() {
291 relinquish_resources_pending_ = true;
292 CheckRelinquishGpuResources();
295 void GpuChannelManager::CheckRelinquishGpuResources() {
296 if (relinquish_resources_pending_ && gpu_channels_.size() <= 1) {
297 relinquish_resources_pending_ = false;
298 if (default_offscreen_surface_.get()) {
299 default_offscreen_surface_->DestroyAndTerminateDisplay();
300 default_offscreen_surface_ = NULL;
302 #if defined(USE_OZONE)
303 ui::OzonePlatform::GetInstance()
304 ->GetGpuPlatformSupport()
305 ->RelinquishGpuResources(
306 base::Bind(&GpuChannelManager::OnResourcesRelinquished,
307 weak_factory_.GetWeakPtr()));
308 #else
309 OnResourcesRelinquished();
310 #endif
314 void GpuChannelManager::OnResourcesRelinquished() {
315 Send(new GpuHostMsg_ResourcesRelinquished());
318 } // namespace content