gpu_channel_host.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
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, 38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const IPC::ChannelHandle& channel_handle, 39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::WaitableEvent* shutdown_event) { 407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK(factory->IsMainThread()); 41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_refptr<GpuChannelHost> host = new GpuChannelHost(factory, gpu_info); 42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) host->Connect(channel_handle, shutdown_event); 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) 68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void GpuChannelHost::Connect(const IPC::ChannelHandle& channel_handle, 69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::WaitableEvent* shutdown_event) { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Open a channel to the GPU process. We pass NULL as the main listener here 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // since we need to filter everything to route it to the right thread. 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<base::MessageLoopProxy> io_loop = factory_->GetIOLoopProxy(); 73868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) channel_.reset(new IPC::SyncChannel(channel_handle, 74868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IPC::Channel::MODE_CLIENT, 75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) NULL, 76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) io_loop.get(), 77868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) true, 78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) shutdown_event)); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) sync_filter_ = new IPC::SyncMessageFilter(shutdown_event); 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; 110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool result = channel_->Send(message.release()); 111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!result) 112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DVLOG(1) << "GpuChannelHost::Send failed: Channel::Send failed"; 113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return result; 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else if (base::MessageLoop::current()) { 115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool result = sync_filter_->Send(message.release()); 116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!result) 117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DVLOG(1) << "GpuChannelHost::Send failed: SyncMessageFilter::Send failed"; 118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return result; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CommandBufferProxyImpl* GpuChannelHost::CreateViewCommandBuffer( 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 surface_id, 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandBufferProxyImpl* share_group, 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<int32>& attribs, 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& active_url, 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::GpuPreference gpu_preference) { 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT1("gpu", 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "GpuChannelHost::CreateViewCommandBuffer", 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "surface_id", 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) surface_id); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GPUCreateCommandBufferConfig init_params; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_params.share_group_id = 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) share_group ? share_group->GetRouteID() : MSG_ROUTING_NONE; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_params.attribs = attribs; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_params.active_url = active_url; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_params.gpu_preference = gpu_preference; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 route_id = factory_->CreateViewCommandBuffer(surface_id, init_params); 142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (route_id == MSG_ROUTING_NONE) { 143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) LOG(ERROR) << "GpuChannelHost::CreateViewCommandBuffer failed."; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandBufferProxyImpl* command_buffer = 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new CommandBufferProxyImpl(this, route_id); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddRoute(route_id, command_buffer->AsWeakPtr()); 1507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) AutoLock lock(context_lock_); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxies_[route_id] = command_buffer; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return command_buffer; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CommandBufferProxyImpl* GpuChannelHost::CreateOffscreenCommandBuffer( 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Size& size, 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandBufferProxyImpl* share_group, 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<int32>& attribs, 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& active_url, 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::GpuPreference gpu_preference) { 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT0("gpu", "GpuChannelHost::CreateOffscreenCommandBuffer"); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GPUCreateCommandBufferConfig init_params; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_params.share_group_id = 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) share_group ? share_group->GetRouteID() : MSG_ROUTING_NONE; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_params.attribs = attribs; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_params.active_url = active_url; 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_params.gpu_preference = gpu_preference; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 route_id; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!Send(new GpuChannelMsg_CreateOffscreenCommandBuffer(size, 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_params, 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &route_id))) { 174a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) LOG(ERROR) << "Failed to send GpuChannelMsg_CreateOffscreenCommandBuffer."; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (route_id == MSG_ROUTING_NONE) { 179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) LOG(ERROR) 180a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << "GpuChannelMsg_CreateOffscreenCommandBuffer returned failure."; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 182a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandBufferProxyImpl* command_buffer = 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new CommandBufferProxyImpl(this, route_id); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddRoute(route_id, command_buffer->AsWeakPtr()); 1877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) AutoLock lock(context_lock_); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxies_[route_id] = command_buffer; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return command_buffer; 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)scoped_ptr<media::VideoDecodeAccelerator> GpuChannelHost::CreateVideoDecoder( 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int command_buffer_route_id, 195a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) media::VideoCodecProfile profile) { 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AutoLock lock(context_lock_); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyMap::iterator it = proxies_.find(command_buffer_route_id); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(it != proxies_.end()); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandBufferProxyImpl* proxy = it->second; 200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return proxy->CreateVideoDecoder(profile).Pass(); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 203a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)scoped_ptr<media::VideoEncodeAccelerator> GpuChannelHost::CreateVideoEncoder() { 2043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) TRACE_EVENT0("gpu", "GpuChannelHost::CreateVideoEncoder"); 2053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<media::VideoEncodeAccelerator> vea; 2073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int32 route_id = MSG_ROUTING_NONE; 2083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!Send(new GpuChannelMsg_CreateVideoEncoder(&route_id))) 2093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return vea.Pass(); 2103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (route_id == MSG_ROUTING_NONE) 2113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return vea.Pass(); 2123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 213a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) vea.reset(new GpuVideoEncodeAcceleratorHost(this, route_id)); 2143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return vea.Pass(); 2153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 2163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelHost::DestroyCommandBuffer( 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandBufferProxyImpl* command_buffer) { 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT0("gpu", "GpuChannelHost::DestroyCommandBuffer"); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int route_id = command_buffer->GetRouteID(); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(new GpuChannelMsg_DestroyCommandBuffer(route_id)); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RemoveRoute(route_id); 2247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) AutoLock lock(context_lock_); 2267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) proxies_.erase(route_id); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete command_buffer; 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelHost::AddRoute( 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int route_id, base::WeakPtr<IPC::Listener> listener) { 2327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK(MessageLoopProxy::current().get()); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<base::MessageLoopProxy> io_loop = factory_->GetIOLoopProxy(); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_loop->PostTask(FROM_HERE, 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&GpuChannelHost::MessageFilter::AddRoute, 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_filter_.get(), route_id, listener, 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MessageLoopProxy::current())); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelHost::RemoveRoute(int route_id) { 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<base::MessageLoopProxy> io_loop = factory_->GetIOLoopProxy(); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_loop->PostTask(FROM_HERE, 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&GpuChannelHost::MessageFilter::RemoveRoute, 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_filter_.get(), route_id)); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::SharedMemoryHandle GpuChannelHost::ShareToGpuProcess( 249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::SharedMemoryHandle source_handle) { 2507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (IsLost()) 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::SharedMemory::NULLHandle(); 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN) 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Windows needs to explicitly duplicate the handle out to another process. 255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::SharedMemoryHandle target_handle; 256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!BrokerDuplicateHandle(source_handle, 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) channel_->peer_pid(), 258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &target_handle, 2590f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) FILE_GENERIC_READ | FILE_GENERIC_WRITE, 2600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 0)) { 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::SharedMemory::NULLHandle(); 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return target_handle; 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else 266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int duped_handle = HANDLE_EINTR(dup(source_handle.fd)); 267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (duped_handle < 0) 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::SharedMemory::NULLHandle(); 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return base::FileDescriptor(duped_handle, true); 271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32 GpuChannelHost::ReserveTransferBufferId() { 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return next_transfer_buffer_id_.GetNext(); 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)gfx::GpuMemoryBufferHandle GpuChannelHost::ShareGpuMemoryBufferToGpuProcess( 2791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) gfx::GpuMemoryBufferHandle source_handle) { 2801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) switch (source_handle.type) { 2811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) case gfx::SHARED_MEMORY_BUFFER: { 2821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) gfx::GpuMemoryBufferHandle handle; 2831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) handle.type = gfx::SHARED_MEMORY_BUFFER; 2841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) handle.handle = ShareToGpuProcess(source_handle.handle); 2851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return handle; 2861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 287a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#if defined(OS_MACOSX) 288a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) case gfx::IO_SURFACE_BUFFER: 289a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return source_handle; 290a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#endif 2911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) default: 2921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) NOTREACHED(); 2931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return gfx::GpuMemoryBufferHandle(); 2941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 2951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 2961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)int32 GpuChannelHost::ReserveGpuMemoryBufferId() { 2981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return next_gpu_memory_buffer_id_.GetNext(); 2991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 3001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)GpuChannelHost::~GpuChannelHost() { 3027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // channel_ must be destroyed on the main thread. 3037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!factory_->IsMainThread()) 3047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) factory_->GetMainLoop()->DeleteSoon(FROM_HERE, channel_.release()); 3057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)GpuChannelHost::MessageFilter::MessageFilter() 3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : lost_(false) { 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GpuChannelHost::MessageFilter::~MessageFilter() {} 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelHost::MessageFilter::AddRoute( 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int route_id, 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WeakPtr<IPC::Listener> listener, 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<MessageLoopProxy> loop) { 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(listeners_.find(route_id) == listeners_.end()); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GpuListenerInfo info; 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info.listener = listener; 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info.loop = loop; 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listeners_[route_id] = info; 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelHost::MessageFilter::RemoveRoute(int route_id) { 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ListenerMap::iterator it = listeners_.find(route_id); 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (it != listeners_.end()) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listeners_.erase(it); 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GpuChannelHost::MessageFilter::OnMessageReceived( 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const IPC::Message& message) { 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Never handle sync message replies or we will deadlock here. 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (message.is_reply()) 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ListenerMap::iterator it = listeners_.find(message.routing_id()); 3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (it == listeners_.end()) 3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const GpuListenerInfo& info = it->second; 3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) info.loop->PostTask( 3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FROM_HERE, 3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind( 3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::IgnoreResult(&IPC::Listener::OnMessageReceived), 3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) info.listener, 3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) message)); 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelHost::MessageFilter::OnChannelError() { 3527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Set the lost state before signalling the proxies. That way, if they 3537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // themselves post a task to recreate the context, they will not try to re-use 3547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // this channel host. 3557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) { 3567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) AutoLock lock(lock_); 3577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) lost_ = true; 3587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 3597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Inform all the proxies that an error has occurred. This will be reported 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // via OpenGL as a lost context. 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ListenerMap::iterator it = listeners_.begin(); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != listeners_.end(); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it++) { 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GpuListenerInfo& info = it->second; 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info.loop->PostTask( 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&IPC::Listener::OnChannelError, info.listener)); 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listeners_.clear(); 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool GpuChannelHost::MessageFilter::IsLost() const { 3757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) AutoLock lock(lock_); 3767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return lost_; 3777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 3787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content 380