| 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 <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 : factory_(factory), | 61 : factory_(factory), |
| 62 gpu_info_(gpu_info), | 62 gpu_info_(gpu_info), |
| 63 gpu_memory_buffer_manager_(gpu_memory_buffer_manager) { | 63 gpu_memory_buffer_manager_(gpu_memory_buffer_manager) { |
| 64 next_transfer_buffer_id_.GetNext(); | 64 next_transfer_buffer_id_.GetNext(); |
| 65 next_image_id_.GetNext(); | 65 next_image_id_.GetNext(); |
| 66 next_route_id_.GetNext(); | 66 next_route_id_.GetNext(); |
| 67 } | 67 } |
| 68 | 68 |
| 69 void GpuChannelHost::Connect(const IPC::ChannelHandle& channel_handle, | 69 void GpuChannelHost::Connect(const IPC::ChannelHandle& channel_handle, |
| 70 base::WaitableEvent* shutdown_event) { | 70 base::WaitableEvent* shutdown_event) { |
| 71 DCHECK(factory_->IsMainThread()); |
| 71 // Open a channel to the GPU process. We pass NULL as the main listener here | 72 // Open a channel to the GPU process. We pass NULL as the main listener here |
| 72 // since we need to filter everything to route it to the right thread. | 73 // since we need to filter everything to route it to the right thread. |
| 73 scoped_refptr<base::MessageLoopProxy> io_loop = factory_->GetIOLoopProxy(); | 74 scoped_refptr<base::MessageLoopProxy> io_loop = factory_->GetIOLoopProxy(); |
| 74 channel_ = IPC::SyncChannel::Create(channel_handle, | 75 channel_ = IPC::SyncChannel::Create(channel_handle, |
| 75 IPC::Channel::MODE_CLIENT, | 76 IPC::Channel::MODE_CLIENT, |
| 76 NULL, | 77 NULL, |
| 77 io_loop.get(), | 78 io_loop.get(), |
| 78 true, | 79 true, |
| 79 shutdown_event); | 80 shutdown_event); |
| 80 | 81 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 99 | 100 |
| 100 // Currently we need to choose between two different mechanisms for sending. | 101 // Currently we need to choose between two different mechanisms for sending. |
| 101 // On the main thread we use the regular channel Send() method, on another | 102 // On the main thread we use the regular channel Send() method, on another |
| 102 // thread we use SyncMessageFilter. We also have to be careful interpreting | 103 // thread we use SyncMessageFilter. We also have to be careful interpreting |
| 103 // IsMainThread() since it might return false during shutdown, | 104 // IsMainThread() since it might return false during shutdown, |
| 104 // impl we are actually calling from the main thread (discard message then). | 105 // impl we are actually calling from the main thread (discard message then). |
| 105 // | 106 // |
| 106 // TODO: Can we just always use sync_filter_ since we setup the channel | 107 // TODO: Can we just always use sync_filter_ since we setup the channel |
| 107 // without a main listener? | 108 // without a main listener? |
| 108 if (factory_->IsMainThread()) { | 109 if (factory_->IsMainThread()) { |
| 110 // channel_ is only modified on the main thread, so we don't need to take a |
| 111 // lock here. |
| 112 if (!channel_) { |
| 113 DVLOG(1) << "GpuChannelHost::Send failed: Channel already destroyed"; |
| 114 return false; |
| 115 } |
| 109 // http://crbug.com/125264 | 116 // http://crbug.com/125264 |
| 110 base::ThreadRestrictions::ScopedAllowWait allow_wait; | 117 base::ThreadRestrictions::ScopedAllowWait allow_wait; |
| 111 bool result = channel_->Send(message.release()); | 118 bool result = channel_->Send(message.release()); |
| 112 if (!result) | 119 if (!result) |
| 113 DVLOG(1) << "GpuChannelHost::Send failed: Channel::Send failed"; | 120 DVLOG(1) << "GpuChannelHost::Send failed: Channel::Send failed"; |
| 114 return result; | 121 return result; |
| 115 } | 122 } |
| 116 | 123 |
| 117 bool result = sync_filter_->Send(message.release()); | 124 bool result = sync_filter_->Send(message.release()); |
| 118 return result; | 125 return result; |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 266 | 273 |
| 267 AutoLock lock(context_lock_); | 274 AutoLock lock(context_lock_); |
| 268 proxies_.erase(route_id); | 275 proxies_.erase(route_id); |
| 269 if (flush_info_.flush_pending && flush_info_.route_id == route_id) | 276 if (flush_info_.flush_pending && flush_info_.route_id == route_id) |
| 270 flush_info_.flush_pending = false; | 277 flush_info_.flush_pending = false; |
| 271 | 278 |
| 272 delete command_buffer; | 279 delete command_buffer; |
| 273 } | 280 } |
| 274 | 281 |
| 275 void GpuChannelHost::DestroyChannel() { | 282 void GpuChannelHost::DestroyChannel() { |
| 276 // channel_ must be destroyed on the main thread. | 283 DCHECK(factory_->IsMainThread()); |
| 277 if (channel_.get() && !factory_->IsMainThread()) | 284 AutoLock lock(context_lock_); |
| 278 factory_->GetMainLoop()->DeleteSoon(FROM_HERE, channel_.release()); | |
| 279 channel_.reset(); | 285 channel_.reset(); |
| 280 } | 286 } |
| 281 | 287 |
| 282 void GpuChannelHost::AddRoute( | 288 void GpuChannelHost::AddRoute( |
| 283 int route_id, base::WeakPtr<IPC::Listener> listener) { | 289 int route_id, base::WeakPtr<IPC::Listener> listener) { |
| 284 DCHECK(MessageLoopProxy::current().get()); | 290 DCHECK(MessageLoopProxy::current().get()); |
| 285 | 291 |
| 286 scoped_refptr<base::MessageLoopProxy> io_loop = factory_->GetIOLoopProxy(); | 292 scoped_refptr<base::MessageLoopProxy> io_loop = factory_->GetIOLoopProxy(); |
| 287 io_loop->PostTask(FROM_HERE, | 293 io_loop->PostTask(FROM_HERE, |
| 288 base::Bind(&GpuChannelHost::MessageFilter::AddRoute, | 294 base::Bind(&GpuChannelHost::MessageFilter::AddRoute, |
| 289 channel_filter_.get(), route_id, listener, | 295 channel_filter_.get(), route_id, listener, |
| 290 MessageLoopProxy::current())); | 296 MessageLoopProxy::current())); |
| 291 } | 297 } |
| 292 | 298 |
| 293 void GpuChannelHost::RemoveRoute(int route_id) { | 299 void GpuChannelHost::RemoveRoute(int route_id) { |
| 294 scoped_refptr<base::MessageLoopProxy> io_loop = factory_->GetIOLoopProxy(); | 300 scoped_refptr<base::MessageLoopProxy> io_loop = factory_->GetIOLoopProxy(); |
| 295 io_loop->PostTask(FROM_HERE, | 301 io_loop->PostTask(FROM_HERE, |
| 296 base::Bind(&GpuChannelHost::MessageFilter::RemoveRoute, | 302 base::Bind(&GpuChannelHost::MessageFilter::RemoveRoute, |
| 297 channel_filter_.get(), route_id)); | 303 channel_filter_.get(), route_id)); |
| 298 } | 304 } |
| 299 | 305 |
| 300 base::SharedMemoryHandle GpuChannelHost::ShareToGpuProcess( | 306 base::SharedMemoryHandle GpuChannelHost::ShareToGpuProcess( |
| 301 base::SharedMemoryHandle source_handle) { | 307 base::SharedMemoryHandle source_handle) { |
| 302 if (IsLost()) | 308 if (IsLost()) |
| 303 return base::SharedMemory::NULLHandle(); | 309 return base::SharedMemory::NULLHandle(); |
| 304 | 310 |
| 305 #if defined(OS_WIN) | 311 #if defined(OS_WIN) |
| 306 // Windows needs to explicitly duplicate the handle out to another process. | 312 // Windows needs to explicitly duplicate the handle out to another process. |
| 307 base::SharedMemoryHandle target_handle; | 313 base::SharedMemoryHandle target_handle; |
| 314 base::ProcessId peer_pid; |
| 315 { |
| 316 AutoLock lock(context_lock_); |
| 317 if (!channel_) |
| 318 return base::SharedMemory::NULLHandle(); |
| 319 peer_pid = channel_->GetPeerPID(); |
| 320 } |
| 308 if (!BrokerDuplicateHandle(source_handle, | 321 if (!BrokerDuplicateHandle(source_handle, |
| 309 channel_->GetPeerPID(), | 322 peer_pid, |
| 310 &target_handle, | 323 &target_handle, |
| 311 FILE_GENERIC_READ | FILE_GENERIC_WRITE, | 324 FILE_GENERIC_READ | FILE_GENERIC_WRITE, |
| 312 0)) { | 325 0)) { |
| 313 return base::SharedMemory::NULLHandle(); | 326 return base::SharedMemory::NULLHandle(); |
| 314 } | 327 } |
| 315 | 328 |
| 316 return target_handle; | 329 return target_handle; |
| 317 #else | 330 #else |
| 318 int duped_handle = HANDLE_EINTR(dup(source_handle.fd)); | 331 int duped_handle = HANDLE_EINTR(dup(source_handle.fd)); |
| 319 if (duped_handle < 0) | 332 if (duped_handle < 0) |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 351 | 364 |
| 352 int32 GpuChannelHost::ReserveImageId() { | 365 int32 GpuChannelHost::ReserveImageId() { |
| 353 return next_image_id_.GetNext(); | 366 return next_image_id_.GetNext(); |
| 354 } | 367 } |
| 355 | 368 |
| 356 int32 GpuChannelHost::GenerateRouteID() { | 369 int32 GpuChannelHost::GenerateRouteID() { |
| 357 return next_route_id_.GetNext(); | 370 return next_route_id_.GetNext(); |
| 358 } | 371 } |
| 359 | 372 |
| 360 GpuChannelHost::~GpuChannelHost() { | 373 GpuChannelHost::~GpuChannelHost() { |
| 361 DestroyChannel(); | 374 #if DCHECK_IS_ON() |
| 375 AutoLock lock(context_lock_); |
| 376 DCHECK(!channel_) |
| 377 << "GpuChannelHost::DestroyChannel must be called before destruction."; |
| 378 #endif |
| 362 } | 379 } |
| 363 | 380 |
| 364 GpuChannelHost::MessageFilter::MessageFilter() | 381 GpuChannelHost::MessageFilter::MessageFilter() |
| 365 : lost_(false) { | 382 : lost_(false) { |
| 366 } | 383 } |
| 367 | 384 |
| 368 GpuChannelHost::MessageFilter::~MessageFilter() {} | 385 GpuChannelHost::MessageFilter::~MessageFilter() {} |
| 369 | 386 |
| 370 void GpuChannelHost::MessageFilter::AddRoute( | 387 void GpuChannelHost::MessageFilter::AddRoute( |
| 371 int route_id, | 388 int route_id, |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 426 | 443 |
| 427 listeners_.clear(); | 444 listeners_.clear(); |
| 428 } | 445 } |
| 429 | 446 |
| 430 bool GpuChannelHost::MessageFilter::IsLost() const { | 447 bool GpuChannelHost::MessageFilter::IsLost() const { |
| 431 AutoLock lock(lock_); | 448 AutoLock lock(lock_); |
| 432 return lost_; | 449 return lost_; |
| 433 } | 450 } |
| 434 | 451 |
| 435 } // namespace content | 452 } // namespace content |
| OLD | NEW |