OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
| 5 #if defined(OS_WIN) |
| 6 #include <windows.h> |
| 7 #endif |
| 8 |
5 #include "chrome/gpu/gpu_channel.h" | 9 #include "chrome/gpu/gpu_channel.h" |
6 | 10 |
7 #include "base/command_line.h" | 11 #include "base/command_line.h" |
8 #include "base/lock.h" | 12 #include "base/lock.h" |
9 #include "base/process_util.h" | 13 #include "base/process_util.h" |
10 #include "base/string_util.h" | 14 #include "base/string_util.h" |
11 #include "base/waitable_event.h" | 15 #include "base/waitable_event.h" |
12 #include "build/build_config.h" | 16 #include "build/build_config.h" |
13 #include "chrome/common/child_process.h" | 17 #include "chrome/common/child_process.h" |
| 18 #include "chrome/common/chrome_constants.h" |
14 #include "chrome/common/chrome_switches.h" | 19 #include "chrome/common/chrome_switches.h" |
15 #include "chrome/common/gpu_messages.h" | 20 #include "chrome/common/gpu_messages.h" |
16 #include "chrome/gpu/gpu_thread.h" | 21 #include "chrome/gpu/gpu_thread.h" |
17 | 22 |
18 #if defined(OS_POSIX) | 23 #if defined(OS_POSIX) |
19 #include "ipc/ipc_channel_posix.h" | 24 #include "ipc/ipc_channel_posix.h" |
20 #endif | 25 #endif |
21 | 26 |
22 namespace { | 27 namespace { |
23 class GpuReleaseTask : public Task { | 28 class GpuReleaseTask : public Task { |
24 public: | 29 public: |
25 void Run() { | 30 void Run() { |
26 ChildProcess::current()->ReleaseProcess(); | 31 ChildProcess::current()->ReleaseProcess(); |
27 } | 32 } |
28 }; | 33 }; |
29 | 34 |
30 typedef base::hash_map<std::string, scoped_refptr<GpuChannel> > | |
31 GpuChannelMap; | |
32 | |
33 // How long we wait before releasing the GPU process. | 35 // How long we wait before releasing the GPU process. |
34 const int kGpuReleaseTimeMS = 10000; | 36 const int kGpuReleaseTimeMS = 10000; |
35 | |
36 GpuChannelMap g_gpu_channels; | |
37 } // namespace anonymous | 37 } // namespace anonymous |
38 | 38 |
39 GpuChannel* GpuChannel::EstablishGpuChannel(int renderer_id) { | 39 GpuChannel::GpuChannel(int renderer_id) |
40 // Map renderer ID to a (single) channel to that process. | 40 : renderer_id_(renderer_id) |
41 std::string channel_name = StringPrintf( | |
42 "%d.r%d", base::GetCurrentProcId(), renderer_id); | |
43 | |
44 scoped_refptr<GpuChannel> channel; | |
45 | |
46 GpuChannelMap::const_iterator iter = g_gpu_channels.find(channel_name); | |
47 if (iter == g_gpu_channels.end()) { | |
48 channel = new GpuChannel; | |
49 } else { | |
50 channel = iter->second; | |
51 } | |
52 | |
53 DCHECK(channel != NULL); | |
54 | |
55 if (!channel->channel_.get()) { | |
56 if (channel->Init(channel_name)) { | |
57 g_gpu_channels[channel_name] = channel; | |
58 } else { | |
59 channel = NULL; | |
60 } | |
61 } | |
62 | |
63 return channel.get(); | |
64 } | |
65 | |
66 GpuChannel::GpuChannel() | |
67 : renderer_id_(-1) | |
68 #if defined(OS_POSIX) | 41 #if defined(OS_POSIX) |
69 , renderer_fd_(-1) | 42 , renderer_fd_(-1) |
70 #endif | 43 #endif |
71 { | 44 { |
72 ChildProcess::current()->AddRefProcess(); | 45 ChildProcess::current()->AddRefProcess(); |
73 const CommandLine* command_line = CommandLine::ForCurrentProcess(); | 46 const CommandLine* command_line = CommandLine::ForCurrentProcess(); |
74 log_messages_ = command_line->HasSwitch(switches::kLogPluginMessages); | 47 log_messages_ = command_line->HasSwitch(switches::kLogPluginMessages); |
75 } | 48 } |
76 | 49 |
77 GpuChannel::~GpuChannel() { | 50 GpuChannel::~GpuChannel() { |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
134 if (!channel_.get()) { | 107 if (!channel_.get()) { |
135 delete message; | 108 delete message; |
136 return false; | 109 return false; |
137 } | 110 } |
138 | 111 |
139 return channel_->Send(message); | 112 return channel_->Send(message); |
140 } | 113 } |
141 | 114 |
142 void GpuChannel::OnControlMessageReceived(const IPC::Message& msg) { | 115 void GpuChannel::OnControlMessageReceived(const IPC::Message& msg) { |
143 IPC_BEGIN_MESSAGE_MAP(GpuChannel, msg) | 116 IPC_BEGIN_MESSAGE_MAP(GpuChannel, msg) |
144 IPC_MESSAGE_HANDLER(GpuChannelMsg_CreateCommandBuffer, | 117 IPC_MESSAGE_HANDLER(GpuChannelMsg_CreateViewCommandBuffer, |
145 OnCreateCommandBuffer) | 118 OnCreateViewCommandBuffer) |
| 119 IPC_MESSAGE_HANDLER(GpuChannelMsg_CreateOffscreenCommandBuffer, |
| 120 OnCreateOffscreenCommandBuffer) |
146 IPC_MESSAGE_HANDLER(GpuChannelMsg_DestroyCommandBuffer, | 121 IPC_MESSAGE_HANDLER(GpuChannelMsg_DestroyCommandBuffer, |
147 OnDestroyCommandBuffer) | 122 OnDestroyCommandBuffer) |
148 IPC_MESSAGE_UNHANDLED_ERROR() | 123 IPC_MESSAGE_UNHANDLED_ERROR() |
149 IPC_END_MESSAGE_MAP() | 124 IPC_END_MESSAGE_MAP() |
150 } | 125 } |
151 | 126 |
152 int GpuChannel::GenerateRouteID() { | 127 int GpuChannel::GenerateRouteID() { |
153 static int last_id = 0; | 128 static int last_id = 0; |
154 return ++last_id; | 129 return ++last_id; |
155 } | 130 } |
156 | 131 |
157 void GpuChannel::OnCreateCommandBuffer(int* route_id) { | 132 void GpuChannel::OnCreateViewCommandBuffer(gfx::NativeViewId view_id, |
| 133 int32* route_id) { |
| 134 *route_id = 0; |
| 135 |
| 136 #if defined(ENABLE_GPU) |
| 137 |
| 138 #if defined(OS_WIN) |
| 139 gfx::NativeView view = gfx::NativeViewFromId(view_id); |
| 140 |
| 141 // Check that the calling renderer is allowed to render to this window. |
| 142 // TODO(apatrick): consider killing the renderer process rather than failing. |
| 143 int view_renderer_id = reinterpret_cast<int>( |
| 144 GetProp(view, chrome::kChromiumRendererIdProperty)); |
| 145 if (view_renderer_id != renderer_id_) |
| 146 return; |
| 147 #else |
| 148 // TODO(apatrick): This needs to be something valid for mac and linux. |
| 149 // Offscreen rendering will work on these platforms but not rendering to the |
| 150 // window. |
| 151 DCHECK_EQ(view_id, 0); |
| 152 gfx::NativeView view = 0; |
| 153 #endif |
| 154 |
| 155 *route_id = GenerateRouteID(); |
| 156 scoped_refptr<GpuCommandBufferStub> stub = new GpuCommandBufferStub( |
| 157 this, view, NULL, gfx::Size(), 0, *route_id); |
| 158 router_.AddRoute(*route_id, stub); |
| 159 stubs_[*route_id] = stub; |
| 160 #endif // ENABLE_GPU |
| 161 } |
| 162 |
| 163 void GpuChannel::OnCreateOffscreenCommandBuffer(int32 parent_route_id, |
| 164 const gfx::Size& size, |
| 165 uint32 parent_texture_id, |
| 166 int32* route_id) { |
158 #if defined(ENABLE_GPU) | 167 #if defined(ENABLE_GPU) |
159 *route_id = GenerateRouteID(); | 168 *route_id = GenerateRouteID(); |
| 169 scoped_refptr<GpuCommandBufferStub> parent_stub; |
| 170 if (parent_route_id != 0) { |
| 171 StubMap::iterator it = stubs_.find(parent_route_id); |
| 172 DCHECK(it != stubs_.end()); |
| 173 parent_stub = it->second; |
| 174 } |
| 175 |
160 scoped_refptr<GpuCommandBufferStub> stub = new GpuCommandBufferStub( | 176 scoped_refptr<GpuCommandBufferStub> stub = new GpuCommandBufferStub( |
161 this, *route_id); | 177 this, |
| 178 NULL, |
| 179 parent_stub.get(), |
| 180 size, |
| 181 parent_texture_id, |
| 182 *route_id); |
162 router_.AddRoute(*route_id, stub); | 183 router_.AddRoute(*route_id, stub); |
163 stubs_[*route_id] = stub; | 184 stubs_[*route_id] = stub; |
164 #else | 185 #else |
165 *route_id = 0; | 186 *route_id = 0; |
166 #endif | 187 #endif |
167 } | 188 } |
168 | 189 |
169 void GpuChannel::OnDestroyCommandBuffer(int route_id) { | 190 void GpuChannel::OnDestroyCommandBuffer(int32 route_id) { |
170 #if defined(ENABLE_GPU) | 191 #if defined(ENABLE_GPU) |
171 StubMap::iterator it = stubs_.find(route_id); | 192 StubMap::iterator it = stubs_.find(route_id); |
172 DCHECK(it != stubs_.end()); | 193 DCHECK(it != stubs_.end()); |
173 stubs_.erase(it); | 194 stubs_.erase(it); |
174 router_.RemoveRoute(route_id); | 195 router_.RemoveRoute(route_id); |
175 #endif | 196 #endif |
176 } | 197 } |
177 | 198 |
178 bool GpuChannel::Init(const std::string& channel_name) { | 199 bool GpuChannel::Init() { |
179 channel_name_ = channel_name; | 200 // Check whether we're already initialized. |
| 201 if (channel_.get()) |
| 202 return true; |
| 203 |
| 204 // Map renderer ID to a (single) channel to that process. |
| 205 std::string channel_name = GetChannelName(); |
180 #if defined(OS_POSIX) | 206 #if defined(OS_POSIX) |
181 // This gets called when the GpuChannel is initially created. At this | 207 // This gets called when the GpuChannel is initially created. At this |
182 // point, create the socketpair and assign the GPU side FD to the channel | 208 // point, create the socketpair and assign the GPU side FD to the channel |
183 // name. Keep the renderer side FD as a member variable in the PluginChannel | 209 // name. Keep the renderer side FD as a member variable in the PluginChannel |
184 // to be able to transmit it through IPC. | 210 // to be able to transmit it through IPC. |
185 int gpu_fd; | 211 int gpu_fd; |
186 IPC::SocketPair(&gpu_fd, &renderer_fd_); | 212 IPC::SocketPair(&gpu_fd, &renderer_fd_); |
187 IPC::AddChannelSocket(channel_name, gpu_fd); | 213 IPC::AddChannelSocket(channel_name, gpu_fd); |
188 #endif | 214 #endif |
189 channel_.reset(new IPC::SyncChannel( | 215 channel_.reset(new IPC::SyncChannel( |
190 channel_name, IPC::Channel::MODE_SERVER, this, NULL, | 216 channel_name, IPC::Channel::MODE_SERVER, this, NULL, |
191 ChildProcess::current()->io_message_loop(), false, | 217 ChildProcess::current()->io_message_loop(), false, |
192 ChildProcess::current()->GetShutDownEvent())); | 218 ChildProcess::current()->GetShutDownEvent())); |
193 return true; | 219 return true; |
194 } | 220 } |
| 221 |
| 222 std::string GpuChannel::GetChannelName() { |
| 223 return StringPrintf("%d.r%d", base::GetCurrentProcId(), renderer_id_); |
| 224 } |
OLD | NEW |