gpu_channel_host.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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) 77d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include <algorithm> 87d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/debug/trace_event.h" 119ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h" 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/posix/eintr_wrapper.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread_restrictions.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/client/command_buffer_proxy_impl.h" 163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "content/common/gpu/client/gpu_video_encode_accelerator_host.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/gpu_messages.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_sync_message_filter.h" 197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN) 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/common/sandbox_init.h" 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::AutoLock; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::MessageLoopProxy; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GpuListenerInfo::GpuListenerInfo() {} 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GpuListenerInfo::~GpuListenerInfo() {} 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// static 357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)scoped_refptr<GpuChannelHost> GpuChannelHost::Create( 367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) GpuChannelHostFactory* factory, 377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const gpu::GPUInfo& gpu_info, 387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const IPC::ChannelHandle& channel_handle) { 397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK(factory->IsMainThread()); 407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_refptr<GpuChannelHost> host = new GpuChannelHost( 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) factory, gpu_info); 427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) host->Connect(channel_handle); 437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return host; 447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// static 471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)bool GpuChannelHost::IsValidGpuMemoryBuffer( 481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) gfx::GpuMemoryBufferHandle handle) { 491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) switch (handle.type) { 501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) case gfx::SHARED_MEMORY_BUFFER: 51a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#if defined(OS_MACOSX) 52a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) case gfx::IO_SURFACE_BUFFER: 53a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#endif 541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return true; 551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) default: 561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return false; 571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)GpuChannelHost::GpuChannelHost(GpuChannelHostFactory* factory, 617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const gpu::GPUInfo& gpu_info) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : factory_(factory), 637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) gpu_info_(gpu_info) { 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) next_transfer_buffer_id_.GetNext(); 651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) next_gpu_memory_buffer_id_.GetNext(); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void GpuChannelHost::Connect(const IPC::ChannelHandle& channel_handle) { 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Open a channel to the GPU process. We pass NULL as the main listener here 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // since we need to filter everything to route it to the right thread. 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<base::MessageLoopProxy> io_loop = factory_->GetIOLoopProxy(); 72868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) channel_.reset(new IPC::SyncChannel(channel_handle, 73868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IPC::Channel::MODE_CLIENT, 74868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) NULL, 75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) io_loop.get(), 76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) true, 77868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) factory_->GetShutDownEvent())); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_filter_ = new IPC::SyncMessageFilter( 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) factory_->GetShutDownEvent()); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_->AddFilter(sync_filter_.get()); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) channel_filter_ = new MessageFilter(); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Install the filter last, because we intercept all leftover 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // messages. 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_->AddFilter(channel_filter_.get()); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool GpuChannelHost::Send(IPC::Message* msg) { 927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Callee takes ownership of message, regardless of whether Send is 937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // successful. See IPC::Sender. 947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<IPC::Message> message(msg); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The GPU process never sends synchronous IPCs so clear the unblock flag to 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // preserve order. 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message->set_unblock(false); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Currently we need to choose between two different mechanisms for sending. 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // On the main thread we use the regular channel Send() method, on another 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // thread we use SyncMessageFilter. We also have to be careful interpreting 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // IsMainThread() since it might return false during shutdown, 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // impl we are actually calling from the main thread (discard message then). 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO: Can we just always use sync_filter_ since we setup the channel 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // without a main listener? 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (factory_->IsMainThread()) { 1087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // http://crbug.com/125264 1097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::ThreadRestrictions::ScopedAllowWait allow_wait; 1107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return channel_->Send(message.release()); 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else if (base::MessageLoop::current()) { 1127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return sync_filter_->Send(message.release()); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CommandBufferProxyImpl* GpuChannelHost::CreateViewCommandBuffer( 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 surface_id, 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandBufferProxyImpl* share_group, 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<int32>& attribs, 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& active_url, 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::GpuPreference gpu_preference) { 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT1("gpu", 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "GpuChannelHost::CreateViewCommandBuffer", 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "surface_id", 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) surface_id); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GPUCreateCommandBufferConfig init_params; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_params.share_group_id = 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) share_group ? share_group->GetRouteID() : MSG_ROUTING_NONE; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_params.attribs = attribs; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_params.active_url = active_url; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_params.gpu_preference = gpu_preference; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 route_id = factory_->CreateViewCommandBuffer(surface_id, init_params); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (route_id == MSG_ROUTING_NONE) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandBufferProxyImpl* command_buffer = 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new CommandBufferProxyImpl(this, route_id); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddRoute(route_id, command_buffer->AsWeakPtr()); 1427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) AutoLock lock(context_lock_); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxies_[route_id] = command_buffer; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return command_buffer; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CommandBufferProxyImpl* GpuChannelHost::CreateOffscreenCommandBuffer( 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Size& size, 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandBufferProxyImpl* share_group, 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<int32>& attribs, 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& active_url, 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::GpuPreference gpu_preference) { 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT0("gpu", "GpuChannelHost::CreateOffscreenCommandBuffer"); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GPUCreateCommandBufferConfig init_params; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_params.share_group_id = 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) share_group ? share_group->GetRouteID() : MSG_ROUTING_NONE; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_params.attribs = attribs; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_params.active_url = active_url; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_params.gpu_preference = gpu_preference; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 route_id; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!Send(new GpuChannelMsg_CreateOffscreenCommandBuffer(size, 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_params, 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &route_id))) { 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (route_id == MSG_ROUTING_NONE) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandBufferProxyImpl* command_buffer = 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new CommandBufferProxyImpl(this, route_id); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddRoute(route_id, command_buffer->AsWeakPtr()); 1757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) AutoLock lock(context_lock_); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxies_[route_id] = command_buffer; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return command_buffer; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)scoped_ptr<media::VideoDecodeAccelerator> GpuChannelHost::CreateVideoDecoder( 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int command_buffer_route_id, 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) media::VideoCodecProfile profile, 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) media::VideoDecodeAccelerator::Client* client) { 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AutoLock lock(context_lock_); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyMap::iterator it = proxies_.find(command_buffer_route_id); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(it != proxies_.end()); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandBufferProxyImpl* proxy = it->second; 189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return proxy->CreateVideoDecoder(profile, client).Pass(); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)scoped_ptr<media::VideoEncodeAccelerator> GpuChannelHost::CreateVideoEncoder( 1933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) media::VideoEncodeAccelerator::Client* client) { 1943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) TRACE_EVENT0("gpu", "GpuChannelHost::CreateVideoEncoder"); 1953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<media::VideoEncodeAccelerator> vea; 1973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int32 route_id = MSG_ROUTING_NONE; 1983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!Send(new GpuChannelMsg_CreateVideoEncoder(&route_id))) 1993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return vea.Pass(); 2003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (route_id == MSG_ROUTING_NONE) 2013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return vea.Pass(); 2023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) vea.reset(new GpuVideoEncodeAcceleratorHost(client, this, route_id)); 2043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return vea.Pass(); 2053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 2063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelHost::DestroyCommandBuffer( 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandBufferProxyImpl* command_buffer) { 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT0("gpu", "GpuChannelHost::DestroyCommandBuffer"); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int route_id = command_buffer->GetRouteID(); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(new GpuChannelMsg_DestroyCommandBuffer(route_id)); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RemoveRoute(route_id); 2147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) AutoLock lock(context_lock_); 2167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) proxies_.erase(route_id); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete command_buffer; 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelHost::AddRoute( 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int route_id, base::WeakPtr<IPC::Listener> listener) { 2227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK(MessageLoopProxy::current().get()); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<base::MessageLoopProxy> io_loop = factory_->GetIOLoopProxy(); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_loop->PostTask(FROM_HERE, 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&GpuChannelHost::MessageFilter::AddRoute, 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_filter_.get(), route_id, listener, 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MessageLoopProxy::current())); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelHost::RemoveRoute(int route_id) { 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<base::MessageLoopProxy> io_loop = factory_->GetIOLoopProxy(); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_loop->PostTask(FROM_HERE, 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&GpuChannelHost::MessageFilter::RemoveRoute, 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_filter_.get(), route_id)); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::SharedMemoryHandle GpuChannelHost::ShareToGpuProcess( 239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::SharedMemoryHandle source_handle) { 2407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (IsLost()) 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::SharedMemory::NULLHandle(); 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN) 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Windows needs to explicitly duplicate the handle out to another process. 245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::SharedMemoryHandle target_handle; 246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!BrokerDuplicateHandle(source_handle, 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) channel_->peer_pid(), 248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &target_handle, 2490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) FILE_GENERIC_READ | FILE_GENERIC_WRITE, 2500f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 0)) { 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::SharedMemory::NULLHandle(); 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return target_handle; 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else 256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int duped_handle = HANDLE_EINTR(dup(source_handle.fd)); 257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (duped_handle < 0) 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::SharedMemory::NULLHandle(); 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return base::FileDescriptor(duped_handle, true); 261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32 GpuChannelHost::ReserveTransferBufferId() { 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return next_transfer_buffer_id_.GetNext(); 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)gfx::GpuMemoryBufferHandle GpuChannelHost::ShareGpuMemoryBufferToGpuProcess( 2691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) gfx::GpuMemoryBufferHandle source_handle) { 2701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) switch (source_handle.type) { 2711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) case gfx::SHARED_MEMORY_BUFFER: { 2721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) gfx::GpuMemoryBufferHandle handle; 2731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) handle.type = gfx::SHARED_MEMORY_BUFFER; 2741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) handle.handle = ShareToGpuProcess(source_handle.handle); 2751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return handle; 2761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 277a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#if defined(OS_MACOSX) 278a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) case gfx::IO_SURFACE_BUFFER: 279a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return source_handle; 280a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#endif 2811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) default: 2821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) NOTREACHED(); 2831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return gfx::GpuMemoryBufferHandle(); 2841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 2851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 2861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)int32 GpuChannelHost::ReserveGpuMemoryBufferId() { 2881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return next_gpu_memory_buffer_id_.GetNext(); 2891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 2901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)GpuChannelHost::~GpuChannelHost() { 2927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // channel_ must be destroyed on the main thread. 2937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!factory_->IsMainThread()) 2947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) factory_->GetMainLoop()->DeleteSoon(FROM_HERE, channel_.release()); 2957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)GpuChannelHost::MessageFilter::MessageFilter() 2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : lost_(false) { 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GpuChannelHost::MessageFilter::~MessageFilter() {} 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelHost::MessageFilter::AddRoute( 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int route_id, 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WeakPtr<IPC::Listener> listener, 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<MessageLoopProxy> loop) { 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(listeners_.find(route_id) == listeners_.end()); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GpuListenerInfo info; 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info.listener = listener; 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info.loop = loop; 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listeners_[route_id] = info; 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelHost::MessageFilter::RemoveRoute(int route_id) { 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ListenerMap::iterator it = listeners_.find(route_id); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (it != listeners_.end()) 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listeners_.erase(it); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GpuChannelHost::MessageFilter::OnMessageReceived( 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const IPC::Message& message) { 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Never handle sync message replies or we will deadlock here. 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (message.is_reply()) 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ListenerMap::iterator it = listeners_.find(message.routing_id()); 3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (it == listeners_.end()) 3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const GpuListenerInfo& info = it->second; 3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) info.loop->PostTask( 3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FROM_HERE, 3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind( 3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::IgnoreResult(&IPC::Listener::OnMessageReceived), 3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) info.listener, 3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) message)); 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelHost::MessageFilter::OnChannelError() { 3427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Set the lost state before signalling the proxies. That way, if they 3437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // themselves post a task to recreate the context, they will not try to re-use 3447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // this channel host. 3457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) { 3467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) AutoLock lock(lock_); 3477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) lost_ = true; 3487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 3497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Inform all the proxies that an error has occurred. This will be reported 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // via OpenGL as a lost context. 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ListenerMap::iterator it = listeners_.begin(); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != listeners_.end(); 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it++) { 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GpuListenerInfo& info = it->second; 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info.loop->PostTask( 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&IPC::Listener::OnChannelError, info.listener)); 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listeners_.clear(); 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool GpuChannelHost::MessageFilter::IsLost() const { 3657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) AutoLock lock(lock_); 3667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return lost_; 3677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 3687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content 370