Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(222)

Side by Side Diff: content/renderer/gpu/gpu_channel_host.cc

Issue 9340012: Move gpu client files to content_common, in content/common/gpu/client (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: remove unneeded enums Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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.
4
5 #include "content/renderer/gpu/gpu_channel_host.h"
6
7 #include "base/bind.h"
8 #include "base/message_loop.h"
9 #include "base/message_loop_proxy.h"
10 #include "content/common/child_thread.h"
11 #include "content/common/gpu/gpu_messages.h"
12 #include "content/renderer/gpu/command_buffer_proxy.h"
13 #include "googleurl/src/gurl.h"
14 #include "ipc/ipc_sync_message_filter.h"
15
16 GpuChannelHostFactory* GpuChannelHostFactory::instance_ = NULL;
17
18 GpuChannelHostFactory::~GpuChannelHostFactory() {
19 DCHECK(!instance_);
20 }
21
22 using base::AutoLock;
23 using base::MessageLoopProxy;
24
25 GpuListenerInfo::GpuListenerInfo() {
26 }
27
28 GpuListenerInfo::~GpuListenerInfo() {
29 }
30
31 GpuChannelHost::MessageFilter::MessageFilter(GpuChannelHost* parent)
32 : parent_(parent) {
33 }
34
35 GpuChannelHost::MessageFilter::~MessageFilter() {
36
37 }
38
39 void GpuChannelHost::MessageFilter::AddRoute(
40 int route_id,
41 base::WeakPtr<IPC::Channel::Listener> listener,
42 scoped_refptr<MessageLoopProxy> loop) {
43 DCHECK(parent_->factory_->IsIOThread());
44 DCHECK(listeners_.find(route_id) == listeners_.end());
45 GpuListenerInfo info;
46 info.listener = listener;
47 info.loop = loop;
48 listeners_[route_id] = info;
49 }
50
51 void GpuChannelHost::MessageFilter::RemoveRoute(int route_id) {
52 DCHECK(parent_->factory_->IsIOThread());
53 ListenerMap::iterator it = listeners_.find(route_id);
54 if (it != listeners_.end())
55 listeners_.erase(it);
56 }
57
58 bool GpuChannelHost::MessageFilter::OnMessageReceived(
59 const IPC::Message& message) {
60 DCHECK(parent_->factory_->IsIOThread());
61 // Never handle sync message replies or we will deadlock here.
62 if (message.is_reply())
63 return false;
64
65 DCHECK(message.routing_id() != MSG_ROUTING_CONTROL);
66
67 ListenerMap::iterator it = listeners_.find(message.routing_id());
68
69 if (it != listeners_.end()) {
70 const GpuListenerInfo& info = it->second;
71 info.loop->PostTask(
72 FROM_HERE,
73 base::Bind(
74 base::IgnoreResult(&IPC::Channel::Listener::OnMessageReceived),
75 info.listener,
76 message));
77 }
78
79 return true;
80 }
81
82 void GpuChannelHost::MessageFilter::OnChannelError() {
83 DCHECK(parent_->factory_->IsIOThread());
84 // Inform all the proxies that an error has occurred. This will be reported
85 // via OpenGL as a lost context.
86 for (ListenerMap::iterator it = listeners_.begin();
87 it != listeners_.end();
88 it++) {
89 const GpuListenerInfo& info = it->second;
90 info.loop->PostTask(
91 FROM_HERE,
92 base::Bind(&IPC::Channel::Listener::OnChannelError, info.listener));
93 }
94
95 listeners_.clear();
96
97 MessageLoop* main_loop = parent_->factory_->GetMainLoop();
98 main_loop->PostTask(FROM_HERE,
99 base::Bind(&GpuChannelHost::OnChannelError, parent_));
100 }
101
102 GpuChannelHost::GpuChannelHost(GpuChannelHostFactory* factory)
103 : factory_(factory),
104 state_(kUnconnected) {
105 }
106
107 GpuChannelHost::~GpuChannelHost() {
108 }
109
110 void GpuChannelHost::Connect(
111 const IPC::ChannelHandle& channel_handle,
112 base::ProcessHandle renderer_process_for_gpu) {
113 DCHECK(factory_->IsMainThread());
114 // Open a channel to the GPU process. We pass NULL as the main listener here
115 // since we need to filter everything to route it to the right thread.
116 channel_.reset(new IPC::SyncChannel(
117 channel_handle, IPC::Channel::MODE_CLIENT, NULL,
118 factory_->GetIOLoopProxy(), true,
119 factory_->GetShutDownEvent()));
120
121 sync_filter_ = new IPC::SyncMessageFilter(
122 factory_->GetShutDownEvent());
123
124 channel_->AddFilter(sync_filter_.get());
125
126 channel_filter_ = new MessageFilter(this);
127
128 // Install the filter last, because we intercept all leftover
129 // messages.
130 channel_->AddFilter(channel_filter_.get());
131
132 // It is safe to send IPC messages before the channel completes the connection
133 // and receives the hello message from the GPU process. The messages get
134 // cached.
135 state_ = kConnected;
136
137 // Notify the GPU process of our process handle. This gives it the ability
138 // to map renderer handles into the GPU process.
139 Send(new GpuChannelMsg_Initialize(renderer_process_for_gpu));
140 }
141
142 void GpuChannelHost::set_gpu_info(const content::GPUInfo& gpu_info) {
143 gpu_info_ = gpu_info;
144 }
145
146 const content::GPUInfo& GpuChannelHost::gpu_info() const {
147 return gpu_info_;
148 }
149
150 void GpuChannelHost::SetStateLost() {
151 state_ = kLost;
152 }
153
154 void GpuChannelHost::OnChannelError() {
155 state_ = kLost;
156
157 // Channel is invalid and will be reinitialized if this host is requested
158 // again.
159 channel_.reset();
160 }
161
162 bool GpuChannelHost::Send(IPC::Message* message) {
163 // The GPU process never sends synchronous IPCs so clear the unblock flag to
164 // preserve order.
165 message->set_unblock(false);
166
167 // Currently we need to choose between two different mechanisms for sending.
168 // On the main thread we use the regular channel Send() method, on another
169 // thread we use SyncMessageFilter. We also have to be careful interpreting
170 // IsMainThread() since it might return false during shutdown,
171 // impl we are actually calling from the main thread (discard message then).
172 //
173 // TODO: Can we just always use sync_filter_ since we setup the channel
174 // without a main listener?
175 if (factory_->IsMainThread()) {
176 if (channel_.get())
177 return channel_->Send(message);
178 } else if (MessageLoop::current()) {
179 return sync_filter_->Send(message);
180 }
181
182 // Callee takes ownership of message, regardless of whether Send is
183 // successful. See IPC::Message::Sender.
184 delete message;
185 return false;
186 }
187
188 CommandBufferProxy* GpuChannelHost::CreateViewCommandBuffer(
189 int32 surface_id,
190 CommandBufferProxy* share_group,
191 const std::string& allowed_extensions,
192 const std::vector<int32>& attribs,
193 const GURL& active_url,
194 gfx::GpuPreference gpu_preference) {
195 DCHECK(factory_->IsMainThread());
196 #if defined(ENABLE_GPU)
197 AutoLock lock(context_lock_);
198 // An error occurred. Need to get the host again to reinitialize it.
199 if (!channel_.get())
200 return NULL;
201
202 GPUCreateCommandBufferConfig init_params;
203 init_params.share_group_id =
204 share_group ? share_group->route_id() : MSG_ROUTING_NONE;
205 init_params.allowed_extensions = allowed_extensions;
206 init_params.attribs = attribs;
207 init_params.active_url = active_url;
208 init_params.gpu_preference = gpu_preference;
209 int32 route_id = factory_->CreateViewCommandBuffer(surface_id, init_params);
210 if (route_id == MSG_ROUTING_NONE)
211 return NULL;
212
213 CommandBufferProxy* command_buffer = new CommandBufferProxy(this, route_id);
214 AddRoute(route_id, command_buffer->AsWeakPtr());
215 proxies_[route_id] = command_buffer;
216 return command_buffer;
217 #else
218 return NULL;
219 #endif
220 }
221
222 GpuVideoDecodeAcceleratorHost* GpuChannelHost::CreateVideoDecoder(
223 int command_buffer_route_id,
224 media::VideoDecodeAccelerator::Profile profile,
225 media::VideoDecodeAccelerator::Client* client) {
226 AutoLock lock(context_lock_);
227 ProxyMap::iterator it = proxies_.find(command_buffer_route_id);
228 DCHECK(it != proxies_.end());
229 CommandBufferProxy* proxy = it->second;
230 return proxy->CreateVideoDecoder(profile, client);
231 }
232
233 CommandBufferProxy* GpuChannelHost::CreateOffscreenCommandBuffer(
234 const gfx::Size& size,
235 CommandBufferProxy* share_group,
236 const std::string& allowed_extensions,
237 const std::vector<int32>& attribs,
238 const GURL& active_url,
239 gfx::GpuPreference gpu_preference) {
240 #if defined(ENABLE_GPU)
241 AutoLock lock(context_lock_);
242 // An error occurred. Need to get the host again to reinitialize it.
243 if (!channel_.get())
244 return NULL;
245
246 GPUCreateCommandBufferConfig init_params;
247 init_params.share_group_id =
248 share_group ? share_group->route_id() : MSG_ROUTING_NONE;
249 init_params.allowed_extensions = allowed_extensions;
250 init_params.attribs = attribs;
251 init_params.active_url = active_url;
252 init_params.gpu_preference = gpu_preference;
253 int32 route_id;
254 if (!Send(new GpuChannelMsg_CreateOffscreenCommandBuffer(size,
255 init_params,
256 &route_id))) {
257 return NULL;
258 }
259
260 if (route_id == MSG_ROUTING_NONE)
261 return NULL;
262
263 CommandBufferProxy* command_buffer = new CommandBufferProxy(this, route_id);
264 AddRoute(route_id, command_buffer->AsWeakPtr());
265 proxies_[route_id] = command_buffer;
266 return command_buffer;
267 #else
268 return NULL;
269 #endif
270 }
271
272 void GpuChannelHost::DestroyCommandBuffer(CommandBufferProxy* command_buffer) {
273 #if defined(ENABLE_GPU)
274 AutoLock lock(context_lock_);
275 Send(new GpuChannelMsg_DestroyCommandBuffer(command_buffer->route_id()));
276
277 // Check the proxy has not already been removed after a channel error.
278 int route_id = command_buffer->route_id();
279 if (proxies_.find(command_buffer->route_id()) != proxies_.end())
280 proxies_.erase(route_id);
281 RemoveRoute(route_id);
282 delete command_buffer;
283 #endif
284 }
285
286 void GpuChannelHost::AddRoute(
287 int route_id, base::WeakPtr<IPC::Channel::Listener> listener) {
288 DCHECK(MessageLoopProxy::current());
289
290 MessageLoopProxy* io_loop = factory_->GetIOLoopProxy();
291 io_loop->PostTask(FROM_HERE,
292 base::Bind(&GpuChannelHost::MessageFilter::AddRoute,
293 channel_filter_.get(), route_id, listener,
294 MessageLoopProxy::current()));
295 }
296
297 void GpuChannelHost::RemoveRoute(int route_id) {
298 MessageLoopProxy* io_loop = factory_->GetIOLoopProxy();
299 io_loop->PostTask(FROM_HERE,
300 base::Bind(&GpuChannelHost::MessageFilter::RemoveRoute,
301 channel_filter_.get(), route_id));
302 }
303
304 bool GpuChannelHost::WillGpuSwitchOccur(
305 bool is_creating_context, gfx::GpuPreference gpu_preference) {
306 bool result = false;
307 if (!Send(new GpuChannelMsg_WillGpuSwitchOccur(is_creating_context,
308 gpu_preference,
309 &result))) {
310 return false;
311 }
312 return result;
313 }
314
315 void GpuChannelHost::ForciblyCloseChannel() {
316 Send(new GpuChannelMsg_CloseChannel());
317 SetStateLost();
318 }
OLDNEW
« no previous file with comments | « content/renderer/gpu/gpu_channel_host.h ('k') | content/renderer/gpu/gpu_video_decode_accelerator_host.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698