blob: bb00d909e0ef6b2af428a90c3dff03ed32a34c12 [file] [log] [blame]
[email protected]7a31f7c2011-03-21 23:22:041// Copyright (c) 2011 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.
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
7#include <string>
8#include <vector>
9
[email protected]7a31f7c2011-03-21 23:22:0410#include "app/win/scoped_com_initializer.h"
11#include "base/command_line.h"
12#include "base/threading/worker_pool.h"
13#include "build/build_config.h"
14#include "chrome/common/child_process_logging.h"
15#include "chrome/common/chrome_switches.h"
16#include "content/common/child_process.h"
17#include "content/common/gpu_messages.h"
[email protected]7a31f7c2011-03-21 23:22:0418#include "ipc/ipc_channel_handle.h"
[email protected]5ae0b282011-03-28 19:24:4919#include "ui/gfx/gl/gl_context.h"
20#include "ui/gfx/gl/gl_implementation.h"
[email protected]7a31f7c2011-03-21 23:22:0421
[email protected]f24a1e2b2011-04-08 01:48:4822GpuChannelManager::GpuChannelManager(IPC::Message::Sender* browser_channel,
[email protected]2dcf7022011-04-15 19:20:4123 GpuWatchdog* watchdog,
[email protected]f24a1e2b2011-04-08 01:48:4824 MessageLoop* io_message_loop,
25 base::WaitableEvent* shutdown_event)
[email protected]0fc35742011-04-13 17:57:5426 : ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)),
27 io_message_loop_(io_message_loop),
[email protected]7a31f7c2011-03-21 23:22:0428 shutdown_event_(shutdown_event),
[email protected]808f7fe72011-03-23 03:49:0229 browser_channel_(browser_channel),
[email protected]2dcf7022011-04-15 19:20:4130 watchdog_(watchdog) {
[email protected]7a31f7c2011-03-21 23:22:0431 DCHECK(browser_channel);
32 DCHECK(io_message_loop);
33 DCHECK(shutdown_event);
34}
35
[email protected]f24a1e2b2011-04-08 01:48:4836GpuChannelManager::~GpuChannelManager() {
[email protected]7a31f7c2011-03-21 23:22:0437 gpu_channels_.clear();
38}
39
[email protected]f24a1e2b2011-04-08 01:48:4840void GpuChannelManager::RemoveChannel(int renderer_id) {
[email protected]7a31f7c2011-03-21 23:22:0441 gpu_channels_.erase(renderer_id);
42}
43
[email protected]f24a1e2b2011-04-08 01:48:4844bool GpuChannelManager::OnMessageReceived(const IPC::Message& msg) {
[email protected]7a31f7c2011-03-21 23:22:0445 bool msg_is_ok = true;
46 bool handled = true;
[email protected]f24a1e2b2011-04-08 01:48:4847 IPC_BEGIN_MESSAGE_MAP_EX(GpuChannelManager, msg, msg_is_ok)
[email protected]7a31f7c2011-03-21 23:22:0448 IPC_MESSAGE_HANDLER(GpuMsg_EstablishChannel, OnEstablishChannel)
49 IPC_MESSAGE_HANDLER(GpuMsg_CloseChannel, OnCloseChannel)
50 IPC_MESSAGE_HANDLER(GpuMsg_CreateViewCommandBuffer,
[email protected]8dc7fbd2011-04-15 00:13:1251 OnCreateViewCommandBuffer)
[email protected]7a31f7c2011-03-21 23:22:0452 IPC_MESSAGE_HANDLER(GpuMsg_Synchronize, OnSynchronize)
[email protected]8dc7fbd2011-04-15 00:13:1253 IPC_MESSAGE_HANDLER(GpuMsg_VisibilityChanged, OnVisibilityChanged)
[email protected]7a31f7c2011-03-21 23:22:0454#if defined(OS_MACOSX)
55 IPC_MESSAGE_HANDLER(GpuMsg_AcceleratedSurfaceBuffersSwappedACK,
56 OnAcceleratedSurfaceBuffersSwappedACK)
57 IPC_MESSAGE_HANDLER(GpuMsg_DestroyCommandBuffer,
58 OnDestroyCommandBuffer)
59#endif
60 IPC_MESSAGE_UNHANDLED(handled = false)
61 IPC_END_MESSAGE_MAP_EX()
62 return handled;
63}
64
[email protected]f24a1e2b2011-04-08 01:48:4865bool GpuChannelManager::Send(IPC::Message* msg) {
[email protected]7a31f7c2011-03-21 23:22:0466 return browser_channel_->Send(msg);
67}
68
[email protected]f24a1e2b2011-04-08 01:48:4869void GpuChannelManager::OnEstablishChannel(int renderer_id) {
[email protected]7a31f7c2011-03-21 23:22:0470 scoped_refptr<GpuChannel> channel;
71 IPC::ChannelHandle channel_handle;
72 GPUInfo gpu_info;
73
74 GpuChannelMap::const_iterator iter = gpu_channels_.find(renderer_id);
75 if (iter == gpu_channels_.end())
[email protected]2dcf7022011-04-15 19:20:4176 channel = new GpuChannel(this, watchdog_, renderer_id);
[email protected]7a31f7c2011-03-21 23:22:0477 else
78 channel = iter->second;
79
80 DCHECK(channel != NULL);
81
82 if (channel->Init(io_message_loop_, shutdown_event_))
83 gpu_channels_[renderer_id] = channel;
84 else
85 channel = NULL;
86
87 if (channel.get()) {
88 channel_handle.name = channel->GetChannelName();
89#if defined(OS_POSIX)
90 // On POSIX, pass the renderer-side FD. Also mark it as auto-close so
91 // that it gets closed after it has been sent.
92 int renderer_fd = channel->GetRendererFileDescriptor();
93 channel_handle.socket = base::FileDescriptor(dup(renderer_fd), true);
94#endif
95 }
96
97 Send(new GpuHostMsg_ChannelEstablished(channel_handle));
98}
99
[email protected]f24a1e2b2011-04-08 01:48:48100void GpuChannelManager::OnCloseChannel(
101 const IPC::ChannelHandle& channel_handle) {
[email protected]7a31f7c2011-03-21 23:22:04102 for (GpuChannelMap::iterator iter = gpu_channels_.begin();
103 iter != gpu_channels_.end(); ++iter) {
104 if (iter->second->GetChannelName() == channel_handle.name) {
105 gpu_channels_.erase(iter);
106 return;
107 }
108 }
109}
110
[email protected]f24a1e2b2011-04-08 01:48:48111void GpuChannelManager::OnSynchronize() {
[email protected]7a31f7c2011-03-21 23:22:04112 Send(new GpuHostMsg_SynchronizeReply());
113}
114
[email protected]8dc7fbd2011-04-15 00:13:12115void GpuChannelManager::OnVisibilityChanged(
116 int32 render_view_id, int32 renderer_id, bool visible) {
117 // TODO(amarinichev): this will be used for context eviction
118}
119
[email protected]f24a1e2b2011-04-08 01:48:48120void GpuChannelManager::OnCreateViewCommandBuffer(
[email protected]7a31f7c2011-03-21 23:22:04121 gfx::PluginWindowHandle window,
122 int32 render_view_id,
123 int32 renderer_id,
124 const GPUCreateCommandBufferConfig& init_params) {
125 int32 route_id = MSG_ROUTING_NONE;
126
127 GpuChannelMap::const_iterator iter = gpu_channels_.find(renderer_id);
128 if (iter != gpu_channels_.end()) {
129 iter->second->CreateViewCommandBuffer(
130 window, render_view_id, init_params, &route_id);
131 }
132
133 Send(new GpuHostMsg_CommandBufferCreated(route_id));
134}
135
136#if defined(OS_MACOSX)
[email protected]f24a1e2b2011-04-08 01:48:48137void GpuChannelManager::OnAcceleratedSurfaceBuffersSwappedACK(
[email protected]7a31f7c2011-03-21 23:22:04138 int renderer_id, int32 route_id, uint64 swap_buffers_count) {
139 GpuChannelMap::const_iterator iter = gpu_channels_.find(renderer_id);
140 if (iter == gpu_channels_.end())
141 return;
142 scoped_refptr<GpuChannel> channel = iter->second;
143 channel->AcceleratedSurfaceBuffersSwapped(route_id, swap_buffers_count);
144}
[email protected]f24a1e2b2011-04-08 01:48:48145void GpuChannelManager::OnDestroyCommandBuffer(
[email protected]7a31f7c2011-03-21 23:22:04146 int renderer_id, int32 renderer_view_id) {
147 GpuChannelMap::const_iterator iter = gpu_channels_.find(renderer_id);
148 if (iter == gpu_channels_.end())
149 return;
150 scoped_refptr<GpuChannel> channel = iter->second;
151 channel->DestroyCommandBufferByViewId(renderer_view_id);
152}
153#endif
[email protected]0fc35742011-04-13 17:57:54154
155void GpuChannelManager::LoseAllContexts() {
156 MessageLoop::current()->PostTask(
157 FROM_HERE, method_factory_.NewRunnableMethod(
158 &GpuChannelManager::OnLoseAllContexts));
159}
160
161void GpuChannelManager::OnLoseAllContexts() {
162 gpu_channels_.clear();
163}