| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 #include "content/common/gpu/client/gpu_channel_host.h" | 5 #include "content/common/gpu/client/gpu_channel_host.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/debug/trace_event.h" | 8 #include "base/debug/trace_event.h" |
| 9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
| 10 #include "base/message_loop_proxy.h" | 10 #include "base/message_loop_proxy.h" |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 45 channel_.reset(new IPC::SyncChannel( | 45 channel_.reset(new IPC::SyncChannel( |
| 46 channel_handle, IPC::Channel::MODE_CLIENT, NULL, | 46 channel_handle, IPC::Channel::MODE_CLIENT, NULL, |
| 47 io_loop, true, | 47 io_loop, true, |
| 48 factory_->GetShutDownEvent())); | 48 factory_->GetShutDownEvent())); |
| 49 | 49 |
| 50 sync_filter_ = new IPC::SyncMessageFilter( | 50 sync_filter_ = new IPC::SyncMessageFilter( |
| 51 factory_->GetShutDownEvent()); | 51 factory_->GetShutDownEvent()); |
| 52 | 52 |
| 53 channel_->AddFilter(sync_filter_.get()); | 53 channel_->AddFilter(sync_filter_.get()); |
| 54 | 54 |
| 55 channel_filter_ = new MessageFilter(this); | 55 channel_filter_ = new MessageFilter(AsWeakPtr(), factory_); |
| 56 | 56 |
| 57 // Install the filter last, because we intercept all leftover | 57 // Install the filter last, because we intercept all leftover |
| 58 // messages. | 58 // messages. |
| 59 channel_->AddFilter(channel_filter_.get()); | 59 channel_->AddFilter(channel_filter_.get()); |
| 60 | 60 |
| 61 // It is safe to send IPC messages before the channel completes the connection | 61 // It is safe to send IPC messages before the channel completes the connection |
| 62 // and receives the hello message from the GPU process. The messages get | 62 // and receives the hello message from the GPU process. The messages get |
| 63 // cached. | 63 // cached. |
| 64 state_ = kConnected; | 64 state_ = kConnected; |
| 65 } | 65 } |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 309 names.end()); | 309 names.end()); |
| 310 } | 310 } |
| 311 | 311 |
| 312 int32 GpuChannelHost::ReserveTransferBufferId() { | 312 int32 GpuChannelHost::ReserveTransferBufferId() { |
| 313 return next_transfer_buffer_id_.GetNext(); | 313 return next_transfer_buffer_id_.GetNext(); |
| 314 } | 314 } |
| 315 | 315 |
| 316 GpuChannelHost::~GpuChannelHost() {} | 316 GpuChannelHost::~GpuChannelHost() {} |
| 317 | 317 |
| 318 | 318 |
| 319 GpuChannelHost::MessageFilter::MessageFilter(GpuChannelHost* parent) | 319 GpuChannelHost::MessageFilter::MessageFilter( |
| 320 : parent_(parent) { | 320 base::WeakPtr<GpuChannelHost> parent, |
| 321 GpuChannelHostFactory* factory) |
| 322 : parent_(parent), |
| 323 factory_(factory) { |
| 321 } | 324 } |
| 322 | 325 |
| 323 GpuChannelHost::MessageFilter::~MessageFilter() {} | 326 GpuChannelHost::MessageFilter::~MessageFilter() {} |
| 324 | 327 |
| 325 void GpuChannelHost::MessageFilter::AddRoute( | 328 void GpuChannelHost::MessageFilter::AddRoute( |
| 326 int route_id, | 329 int route_id, |
| 327 base::WeakPtr<IPC::Listener> listener, | 330 base::WeakPtr<IPC::Listener> listener, |
| 328 scoped_refptr<MessageLoopProxy> loop) { | 331 scoped_refptr<MessageLoopProxy> loop) { |
| 329 DCHECK(parent_->factory_->IsIOThread()); | 332 DCHECK(factory_->IsIOThread()); |
| 330 DCHECK(listeners_.find(route_id) == listeners_.end()); | 333 DCHECK(listeners_.find(route_id) == listeners_.end()); |
| 331 GpuListenerInfo info; | 334 GpuListenerInfo info; |
| 332 info.listener = listener; | 335 info.listener = listener; |
| 333 info.loop = loop; | 336 info.loop = loop; |
| 334 listeners_[route_id] = info; | 337 listeners_[route_id] = info; |
| 335 } | 338 } |
| 336 | 339 |
| 337 void GpuChannelHost::MessageFilter::RemoveRoute(int route_id) { | 340 void GpuChannelHost::MessageFilter::RemoveRoute(int route_id) { |
| 338 DCHECK(parent_->factory_->IsIOThread()); | 341 DCHECK(factory_->IsIOThread()); |
| 339 ListenerMap::iterator it = listeners_.find(route_id); | 342 ListenerMap::iterator it = listeners_.find(route_id); |
| 340 if (it != listeners_.end()) | 343 if (it != listeners_.end()) |
| 341 listeners_.erase(it); | 344 listeners_.erase(it); |
| 342 } | 345 } |
| 343 | 346 |
| 344 bool GpuChannelHost::MessageFilter::OnMessageReceived( | 347 bool GpuChannelHost::MessageFilter::OnMessageReceived( |
| 345 const IPC::Message& message) { | 348 const IPC::Message& message) { |
| 346 DCHECK(parent_->factory_->IsIOThread()); | 349 DCHECK(factory_->IsIOThread()); |
| 347 | 350 |
| 348 // Never handle sync message replies or we will deadlock here. | 351 // Never handle sync message replies or we will deadlock here. |
| 349 if (message.is_reply()) | 352 if (message.is_reply()) |
| 350 return false; | 353 return false; |
| 351 | 354 |
| 352 if (message.routing_id() == MSG_ROUTING_CONTROL) { | 355 if (message.routing_id() == MSG_ROUTING_CONTROL) { |
| 353 MessageLoop* main_loop = parent_->factory_->GetMainLoop(); | 356 MessageLoop* main_loop = factory_->GetMainLoop(); |
| 354 main_loop->PostTask(FROM_HERE, | 357 main_loop->PostTask(FROM_HERE, |
| 355 base::Bind(&GpuChannelHost::OnMessageReceived, | 358 base::Bind(&GpuChannelHost::OnMessageReceived, |
| 356 parent_, | 359 parent_, |
| 357 message)); | 360 message)); |
| 358 return true; | 361 return true; |
| 359 } | 362 } |
| 360 | 363 |
| 361 ListenerMap::iterator it = listeners_.find(message.routing_id()); | 364 ListenerMap::iterator it = listeners_.find(message.routing_id()); |
| 362 | 365 |
| 363 if (it != listeners_.end()) { | 366 if (it != listeners_.end()) { |
| 364 const GpuListenerInfo& info = it->second; | 367 const GpuListenerInfo& info = it->second; |
| 365 info.loop->PostTask( | 368 info.loop->PostTask( |
| 366 FROM_HERE, | 369 FROM_HERE, |
| 367 base::Bind( | 370 base::Bind( |
| 368 base::IgnoreResult(&IPC::Listener::OnMessageReceived), | 371 base::IgnoreResult(&IPC::Listener::OnMessageReceived), |
| 369 info.listener, | 372 info.listener, |
| 370 message)); | 373 message)); |
| 371 } | 374 } |
| 372 | 375 |
| 373 return true; | 376 return true; |
| 374 } | 377 } |
| 375 | 378 |
| 376 void GpuChannelHost::MessageFilter::OnChannelError() { | 379 void GpuChannelHost::MessageFilter::OnChannelError() { |
| 377 DCHECK(parent_->factory_->IsIOThread()); | 380 DCHECK(factory_->IsIOThread()); |
| 378 | 381 |
| 379 // Post the task to signal the GpuChannelHost before the proxies. That way, if | 382 // Post the task to signal the GpuChannelHost before the proxies. That way, if |
| 380 // they themselves post a task to recreate the context, they will not try to | 383 // they themselves post a task to recreate the context, they will not try to |
| 381 // re-use this channel host before it has a chance to mark itself lost. | 384 // re-use this channel host before it has a chance to mark itself lost. |
| 382 MessageLoop* main_loop = parent_->factory_->GetMainLoop(); | 385 MessageLoop* main_loop = factory_->GetMainLoop(); |
| 383 main_loop->PostTask(FROM_HERE, | 386 main_loop->PostTask(FROM_HERE, |
| 384 base::Bind(&GpuChannelHost::OnChannelError, parent_)); | 387 base::Bind(&GpuChannelHost::OnChannelError, parent_)); |
| 385 // Inform all the proxies that an error has occurred. This will be reported | 388 // Inform all the proxies that an error has occurred. This will be reported |
| 386 // via OpenGL as a lost context. | 389 // via OpenGL as a lost context. |
| 387 for (ListenerMap::iterator it = listeners_.begin(); | 390 for (ListenerMap::iterator it = listeners_.begin(); |
| 388 it != listeners_.end(); | 391 it != listeners_.end(); |
| 389 it++) { | 392 it++) { |
| 390 const GpuListenerInfo& info = it->second; | 393 const GpuListenerInfo& info = it->second; |
| 391 info.loop->PostTask( | 394 info.loop->PostTask( |
| 392 FROM_HERE, | 395 FROM_HERE, |
| 393 base::Bind(&IPC::Listener::OnChannelError, info.listener)); | 396 base::Bind(&IPC::Listener::OnChannelError, info.listener)); |
| 394 } | 397 } |
| 395 | 398 |
| 396 listeners_.clear(); | 399 listeners_.clear(); |
| 397 } | 400 } |
| 398 | 401 |
| 399 } // namespace content | 402 } // namespace content |
| OLD | NEW |