gpu_channel_host.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/client/gpu_channel_host.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/debug/trace_event.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/message_loop.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/message_loop_proxy.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread_restrictions.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/client/command_buffer_proxy_impl.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/gpu_messages.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "googleurl/src/gurl.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "gpu/command_buffer/common/mailbox.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_sync_message_filter.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN) 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/common/sandbox_init.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::AutoLock; 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::MessageLoopProxy; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GpuListenerInfo::GpuListenerInfo() {} 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GpuListenerInfo::~GpuListenerInfo() {} 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GpuChannelHost::GpuChannelHost( 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GpuChannelHostFactory* factory, int gpu_host_id, int client_id) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : factory_(factory), 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_id_(client_id), 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gpu_host_id_(gpu_host_id), 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_(kUnconnected) { 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) next_transfer_buffer_id_.GetNext(); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelHost::Connect( 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const IPC::ChannelHandle& channel_handle) { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(factory_->IsMainThread()); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Open a channel to the GPU process. We pass NULL as the main listener here 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // since we need to filter everything to route it to the right thread. 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<base::MessageLoopProxy> io_loop = factory_->GetIOLoopProxy(); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_.reset(new IPC::SyncChannel( 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_handle, IPC::Channel::MODE_CLIENT, NULL, 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_loop, true, 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) factory_->GetShutDownEvent())); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_filter_ = new IPC::SyncMessageFilter( 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) factory_->GetShutDownEvent()); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_->AddFilter(sync_filter_.get()); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) channel_filter_ = new MessageFilter(AsWeakPtr(), factory_); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Install the filter last, because we intercept all leftover 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // messages. 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_->AddFilter(channel_filter_.get()); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It is safe to send IPC messages before the channel completes the connection 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and receives the hello message from the GPU process. The messages get 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // cached. 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_ = kConnected; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelHost::set_gpu_info(const GPUInfo& gpu_info) { 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gpu_info_ = gpu_info; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelHost::SetStateLost() { 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_ = kLost; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GPUInfo& GpuChannelHost::gpu_info() const { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return gpu_info_; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelHost::OnMessageReceived(const IPC::Message& message) { 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool handled = true; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_BEGIN_MESSAGE_MAP(GpuChannelHost, message) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(GpuChannelMsg_GenerateMailboxNamesReply, 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnGenerateMailboxNamesReply) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_UNHANDLED(handled = false) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_END_MESSAGE_MAP() 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(handled); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelHost::OnChannelError() { 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_ = kLost; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Channel is invalid and will be reinitialized if this host is requested 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // again. 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_.reset(); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GpuChannelHost::Send(IPC::Message* message) { 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The GPU process never sends synchronous IPCs so clear the unblock flag to 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // preserve order. 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message->set_unblock(false); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Currently we need to choose between two different mechanisms for sending. 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // On the main thread we use the regular channel Send() method, on another 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // thread we use SyncMessageFilter. We also have to be careful interpreting 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // IsMainThread() since it might return false during shutdown, 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // impl we are actually calling from the main thread (discard message then). 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO: Can we just always use sync_filter_ since we setup the channel 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // without a main listener? 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (factory_->IsMainThread()) { 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (channel_.get()) { 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // http://crbug.com/125264 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ThreadRestrictions::ScopedAllowWait allow_wait; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return channel_->Send(message); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (MessageLoop::current()) { 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sync_filter_->Send(message); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Callee takes ownership of message, regardless of whether Send is 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // successful. See IPC::Sender. 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete message; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CommandBufferProxyImpl* GpuChannelHost::CreateViewCommandBuffer( 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 surface_id, 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandBufferProxyImpl* share_group, 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& allowed_extensions, 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<int32>& attribs, 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& active_url, 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::GpuPreference gpu_preference) { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT1("gpu", 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "GpuChannelHost::CreateViewCommandBuffer", 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "surface_id", 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) surface_id); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AutoLock lock(context_lock_); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // An error occurred. Need to get the host again to reinitialize it. 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!channel_.get()) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GPUCreateCommandBufferConfig init_params; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_params.share_group_id = 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) share_group ? share_group->GetRouteID() : MSG_ROUTING_NONE; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_params.allowed_extensions = allowed_extensions; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_params.attribs = attribs; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_params.active_url = active_url; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_params.gpu_preference = gpu_preference; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 route_id = factory_->CreateViewCommandBuffer(surface_id, init_params); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (route_id == MSG_ROUTING_NONE) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandBufferProxyImpl* command_buffer = 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new CommandBufferProxyImpl(this, route_id); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddRoute(route_id, command_buffer->AsWeakPtr()); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxies_[route_id] = command_buffer; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return command_buffer; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CommandBufferProxyImpl* GpuChannelHost::CreateOffscreenCommandBuffer( 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Size& size, 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandBufferProxyImpl* share_group, 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& allowed_extensions, 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<int32>& attribs, 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& active_url, 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::GpuPreference gpu_preference) { 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT0("gpu", "GpuChannelHost::CreateOffscreenCommandBuffer"); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AutoLock lock(context_lock_); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // An error occurred. Need to get the host again to reinitialize it. 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!channel_.get()) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GPUCreateCommandBufferConfig init_params; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_params.share_group_id = 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) share_group ? share_group->GetRouteID() : MSG_ROUTING_NONE; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_params.allowed_extensions = allowed_extensions; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_params.attribs = attribs; 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_params.active_url = active_url; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_params.gpu_preference = gpu_preference; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 route_id; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!Send(new GpuChannelMsg_CreateOffscreenCommandBuffer(size, 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_params, 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &route_id))) { 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (route_id == MSG_ROUTING_NONE) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandBufferProxyImpl* command_buffer = 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new CommandBufferProxyImpl(this, route_id); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddRoute(route_id, command_buffer->AsWeakPtr()); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxies_[route_id] = command_buffer; 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return command_buffer; 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GpuVideoDecodeAcceleratorHost* GpuChannelHost::CreateVideoDecoder( 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int command_buffer_route_id, 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) media::VideoCodecProfile profile, 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) media::VideoDecodeAccelerator::Client* client) { 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AutoLock lock(context_lock_); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyMap::iterator it = proxies_.find(command_buffer_route_id); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(it != proxies_.end()); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandBufferProxyImpl* proxy = it->second; 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return proxy->CreateVideoDecoder(profile, client); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelHost::DestroyCommandBuffer( 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandBufferProxyImpl* command_buffer) { 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT0("gpu", "GpuChannelHost::DestroyCommandBuffer"); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AutoLock lock(context_lock_); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int route_id = command_buffer->GetRouteID(); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(new GpuChannelMsg_DestroyCommandBuffer(route_id)); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check the proxy has not already been removed after a channel error. 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (proxies_.find(route_id) != proxies_.end()) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxies_.erase(route_id); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RemoveRoute(route_id); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete command_buffer; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GpuChannelHost::CollectRenderingStatsForSurface( 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int surface_id, GpuRenderingStats* stats) { 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT0("gpu", "GpuChannelHost::CollectRenderingStats"); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Send(new GpuChannelMsg_CollectRenderingStatsForSurface(surface_id, 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stats)); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelHost::AddRoute( 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int route_id, base::WeakPtr<IPC::Listener> listener) { 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(MessageLoopProxy::current()); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<base::MessageLoopProxy> io_loop = factory_->GetIOLoopProxy(); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_loop->PostTask(FROM_HERE, 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&GpuChannelHost::MessageFilter::AddRoute, 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_filter_.get(), route_id, listener, 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MessageLoopProxy::current())); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelHost::RemoveRoute(int route_id) { 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<base::MessageLoopProxy> io_loop = factory_->GetIOLoopProxy(); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_loop->PostTask(FROM_HERE, 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&GpuChannelHost::MessageFilter::RemoveRoute, 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_filter_.get(), route_id)); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::SharedMemoryHandle GpuChannelHost::ShareToGpuProcess( 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::SharedMemory* shared_memory) { 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AutoLock lock(context_lock_); 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!channel_.get()) 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::SharedMemory::NULLHandle(); 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::SharedMemoryHandle handle; 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN) 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Windows needs to explicitly duplicate the handle out to another process. 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!BrokerDuplicateHandle(shared_memory->handle(), 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) channel_->peer_pid(), 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &handle, 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FILE_MAP_WRITE, 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 0)) { 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::SharedMemory::NULLHandle(); 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!shared_memory->ShareToProcess(channel_->peer_pid(), &handle)) 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::SharedMemory::NULLHandle(); 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return handle; 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GpuChannelHost::GenerateMailboxNames(unsigned num, 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<gpu::Mailbox>* names) { 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT0("gpu", "GenerateMailboxName"); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AutoLock lock(context_lock_); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (num > mailbox_name_pool_.size()) { 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!Send(new GpuChannelMsg_GenerateMailboxNames(num, names))) 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) names->insert(names->begin(), 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mailbox_name_pool_.end() - num, 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mailbox_name_pool_.end()); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mailbox_name_pool_.erase(mailbox_name_pool_.end() - num, 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mailbox_name_pool_.end()); 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const unsigned ideal_mailbox_pool_size = 100; 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (mailbox_name_pool_.size() < ideal_mailbox_pool_size / 2) { 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(new GpuChannelMsg_GenerateMailboxNamesAsync( 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ideal_mailbox_pool_size - mailbox_name_pool_.size())); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelHost::OnGenerateMailboxNamesReply( 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::vector<gpu::Mailbox>& names) { 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT0("gpu", "OnGenerateMailboxNamesReply"); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AutoLock lock(context_lock_); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mailbox_name_pool_.insert(mailbox_name_pool_.end(), 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) names.begin(), 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) names.end()); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32 GpuChannelHost::ReserveTransferBufferId() { 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return next_transfer_buffer_id_.GetNext(); 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GpuChannelHost::~GpuChannelHost() {} 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GpuChannelHost::MessageFilter::MessageFilter( 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::WeakPtr<GpuChannelHost> parent, 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GpuChannelHostFactory* factory) 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : parent_(parent), 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) factory_(factory) { 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GpuChannelHost::MessageFilter::~MessageFilter() {} 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelHost::MessageFilter::AddRoute( 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int route_id, 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WeakPtr<IPC::Listener> listener, 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<MessageLoopProxy> loop) { 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(factory_->IsIOThread()); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(listeners_.find(route_id) == listeners_.end()); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GpuListenerInfo info; 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info.listener = listener; 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info.loop = loop; 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listeners_[route_id] = info; 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelHost::MessageFilter::RemoveRoute(int route_id) { 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(factory_->IsIOThread()); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ListenerMap::iterator it = listeners_.find(route_id); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (it != listeners_.end()) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listeners_.erase(it); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GpuChannelHost::MessageFilter::OnMessageReceived( 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const IPC::Message& message) { 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(factory_->IsIOThread()); 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Never handle sync message replies or we will deadlock here. 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (message.is_reply()) 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (message.routing_id() == MSG_ROUTING_CONTROL) { 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MessageLoop* main_loop = factory_->GetMainLoop(); 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) main_loop->PostTask(FROM_HERE, 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&GpuChannelHost::OnMessageReceived, 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent_, 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message)); 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ListenerMap::iterator it = listeners_.find(message.routing_id()); 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (it != listeners_.end()) { 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GpuListenerInfo& info = it->second; 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info.loop->PostTask( 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind( 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::IgnoreResult(&IPC::Listener::OnMessageReceived), 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info.listener, 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message)); 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelHost::MessageFilter::OnChannelError() { 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(factory_->IsIOThread()); 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Post the task to signal the GpuChannelHost before the proxies. That way, if 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // they themselves post a task to recreate the context, they will not try to 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // re-use this channel host before it has a chance to mark itself lost. 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MessageLoop* main_loop = factory_->GetMainLoop(); 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) main_loop->PostTask(FROM_HERE, 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&GpuChannelHost::OnChannelError, parent_)); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Inform all the proxies that an error has occurred. This will be reported 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // via OpenGL as a lost context. 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ListenerMap::iterator it = listeners_.begin(); 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != listeners_.end(); 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it++) { 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GpuListenerInfo& info = it->second; 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info.loop->PostTask( 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&IPC::Listener::OnChannelError, info.listener)); 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listeners_.clear(); 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content 404