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" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/gpu_messages.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_sync_message_filter.h" 187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN) 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/common/sandbox_init.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::AutoLock; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::MessageLoopProxy; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GpuListenerInfo::GpuListenerInfo() {} 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GpuListenerInfo::~GpuListenerInfo() {} 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// static 347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)scoped_refptr<GpuChannelHost> GpuChannelHost::Create( 357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) GpuChannelHostFactory* factory, 367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const gpu::GPUInfo& gpu_info, 37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const IPC::ChannelHandle& channel_handle, 38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::WaitableEvent* shutdown_event) { 397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK(factory->IsMainThread()); 40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_refptr<GpuChannelHost> host = new GpuChannelHost(factory, gpu_info); 41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) host->Connect(channel_handle, shutdown_event); 427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return host; 437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// static 461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)bool GpuChannelHost::IsValidGpuMemoryBuffer( 471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) gfx::GpuMemoryBufferHandle handle) { 481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) switch (handle.type) { 491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) case gfx::SHARED_MEMORY_BUFFER: 50a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#if defined(OS_MACOSX) 51a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) case gfx::IO_SURFACE_BUFFER: 52a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#endif 534ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch#if defined(OS_ANDROID) 544ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch case gfx::SURFACE_TEXTURE_BUFFER: 554ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch#endif 565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if defined(USE_X11) 575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case gfx::X11_PIXMAP_BUFFER: 585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif 591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return true; 601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) default: 611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return false; 621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)GpuChannelHost::GpuChannelHost(GpuChannelHostFactory* factory, 667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const gpu::GPUInfo& gpu_info) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : factory_(factory), 687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) gpu_info_(gpu_info) { 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) next_transfer_buffer_id_.GetNext(); 701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) next_gpu_memory_buffer_id_.GetNext(); 71c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch next_route_id_.GetNext(); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void GpuChannelHost::Connect(const IPC::ChannelHandle& channel_handle, 75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::WaitableEvent* shutdown_event) { 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Open a channel to the GPU process. We pass NULL as the main listener here 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // since we need to filter everything to route it to the right thread. 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<base::MessageLoopProxy> io_loop = factory_->GetIOLoopProxy(); 7946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) channel_ = IPC::SyncChannel::Create(channel_handle, 80868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IPC::Channel::MODE_CLIENT, 81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) NULL, 82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) io_loop.get(), 83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) true, 8446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) shutdown_event); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) sync_filter_ = new IPC::SyncMessageFilter(shutdown_event); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_->AddFilter(sync_filter_.get()); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) channel_filter_ = new MessageFilter(); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Install the filter last, because we intercept all leftover 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // messages. 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_->AddFilter(channel_filter_.get()); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool GpuChannelHost::Send(IPC::Message* msg) { 987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Callee takes ownership of message, regardless of whether Send is 997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // successful. See IPC::Sender. 1007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<IPC::Message> message(msg); 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()) { 1147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // http://crbug.com/125264 1157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::ThreadRestrictions::ScopedAllowWait allow_wait; 116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool result = channel_->Send(message.release()); 117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!result) 118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DVLOG(1) << "GpuChannelHost::Send failed: Channel::Send failed"; 119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return result; 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else if (base::MessageLoop::current()) { 121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool result = sync_filter_->Send(message.release()); 122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!result) 123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DVLOG(1) << "GpuChannelHost::Send failed: SyncMessageFilter::Send failed"; 124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return result; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CommandBufferProxyImpl* GpuChannelHost::CreateViewCommandBuffer( 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 surface_id, 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandBufferProxyImpl* share_group, 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) GPUCreateCommandBufferConfig init_params; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_params.share_group_id = 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) share_group ? share_group->GetRouteID() : MSG_ROUTING_NONE; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_params.attribs = attribs; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_params.active_url = active_url; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_params.gpu_preference = gpu_preference; 147c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch int32 route_id = GenerateRouteID(); 148116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CreateCommandBufferResult result = factory_->CreateViewCommandBuffer( 149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch surface_id, init_params, route_id); 150116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (result != CREATE_COMMAND_BUFFER_SUCCEEDED) { 151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) LOG(ERROR) << "GpuChannelHost::CreateViewCommandBuffer failed."; 152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 153116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (result == CREATE_COMMAND_BUFFER_FAILED_AND_CHANNEL_LOST) { 154116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // The GPU channel needs to be considered lost. The caller will 155116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // then set up a new connection, and the GPU channel and any 156116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // view command buffers will all be associated with the same GPU 157116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // process. 158116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(MessageLoopProxy::current().get()); 159116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 160116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_refptr<base::MessageLoopProxy> io_loop = 161116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch factory_->GetIOLoopProxy(); 162116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch io_loop->PostTask( 163116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch FROM_HERE, 164116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Bind(&GpuChannelHost::MessageFilter::OnChannelError, 165116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch channel_filter_.get())); 166116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandBufferProxyImpl* command_buffer = 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new CommandBufferProxyImpl(this, route_id); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddRoute(route_id, command_buffer->AsWeakPtr()); 1747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) AutoLock lock(context_lock_); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxies_[route_id] = command_buffer; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return command_buffer; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CommandBufferProxyImpl* GpuChannelHost::CreateOffscreenCommandBuffer( 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Size& size, 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandBufferProxyImpl* share_group, 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<int32>& attribs, 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& active_url, 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::GpuPreference gpu_preference) { 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT0("gpu", "GpuChannelHost::CreateOffscreenCommandBuffer"); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GPUCreateCommandBufferConfig init_params; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_params.share_group_id = 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) share_group ? share_group->GetRouteID() : MSG_ROUTING_NONE; 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_params.attribs = attribs; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_params.active_url = active_url; 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_params.gpu_preference = gpu_preference; 194c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch int32 route_id = GenerateRouteID(); 195c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch bool succeeded = false; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!Send(new GpuChannelMsg_CreateOffscreenCommandBuffer(size, 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_params, 198c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch route_id, 199c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch &succeeded))) { 200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) LOG(ERROR) << "Failed to send GpuChannelMsg_CreateOffscreenCommandBuffer."; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 204c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!succeeded) { 205a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) LOG(ERROR) 206a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << "GpuChannelMsg_CreateOffscreenCommandBuffer returned failure."; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 208a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandBufferProxyImpl* command_buffer = 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new CommandBufferProxyImpl(this, route_id); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddRoute(route_id, command_buffer->AsWeakPtr()); 2137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) AutoLock lock(context_lock_); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxies_[route_id] = command_buffer; 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return command_buffer; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)scoped_ptr<media::VideoDecodeAccelerator> GpuChannelHost::CreateVideoDecoder( 220c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch int command_buffer_route_id) { 221c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch TRACE_EVENT0("gpu", "GpuChannelHost::CreateVideoDecoder"); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AutoLock lock(context_lock_); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyMap::iterator it = proxies_.find(command_buffer_route_id); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(it != proxies_.end()); 225c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return it->second->CreateVideoDecoder(); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 228c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochscoped_ptr<media::VideoEncodeAccelerator> GpuChannelHost::CreateVideoEncoder( 229c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch int command_buffer_route_id) { 2303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) TRACE_EVENT0("gpu", "GpuChannelHost::CreateVideoEncoder"); 231c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch AutoLock lock(context_lock_); 232c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ProxyMap::iterator it = proxies_.find(command_buffer_route_id); 233c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(it != proxies_.end()); 234c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return it->second->CreateVideoEncoder(); 2353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 2363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelHost::DestroyCommandBuffer( 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandBufferProxyImpl* command_buffer) { 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT0("gpu", "GpuChannelHost::DestroyCommandBuffer"); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int route_id = command_buffer->GetRouteID(); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(new GpuChannelMsg_DestroyCommandBuffer(route_id)); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RemoveRoute(route_id); 2447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) AutoLock lock(context_lock_); 2467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) proxies_.erase(route_id); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete command_buffer; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelHost::AddRoute( 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int route_id, base::WeakPtr<IPC::Listener> listener) { 2527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK(MessageLoopProxy::current().get()); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<base::MessageLoopProxy> io_loop = factory_->GetIOLoopProxy(); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_loop->PostTask(FROM_HERE, 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&GpuChannelHost::MessageFilter::AddRoute, 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_filter_.get(), route_id, listener, 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MessageLoopProxy::current())); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelHost::RemoveRoute(int route_id) { 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<base::MessageLoopProxy> io_loop = factory_->GetIOLoopProxy(); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_loop->PostTask(FROM_HERE, 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&GpuChannelHost::MessageFilter::RemoveRoute, 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_filter_.get(), route_id)); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::SharedMemoryHandle GpuChannelHost::ShareToGpuProcess( 269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::SharedMemoryHandle source_handle) { 2707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (IsLost()) 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::SharedMemory::NULLHandle(); 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN) 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Windows needs to explicitly duplicate the handle out to another process. 275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::SharedMemoryHandle target_handle; 276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!BrokerDuplicateHandle(source_handle, 27746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) channel_->GetPeerPID(), 278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &target_handle, 2790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) FILE_GENERIC_READ | FILE_GENERIC_WRITE, 2800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 0)) { 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::SharedMemory::NULLHandle(); 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return target_handle; 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else 286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int duped_handle = HANDLE_EINTR(dup(source_handle.fd)); 287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (duped_handle < 0) 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::SharedMemory::NULLHandle(); 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return base::FileDescriptor(duped_handle, true); 291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32 GpuChannelHost::ReserveTransferBufferId() { 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return next_transfer_buffer_id_.GetNext(); 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)gfx::GpuMemoryBufferHandle GpuChannelHost::ShareGpuMemoryBufferToGpuProcess( 2991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) gfx::GpuMemoryBufferHandle source_handle) { 3001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) switch (source_handle.type) { 3011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) case gfx::SHARED_MEMORY_BUFFER: { 3021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) gfx::GpuMemoryBufferHandle handle; 3031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) handle.type = gfx::SHARED_MEMORY_BUFFER; 3041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) handle.handle = ShareToGpuProcess(source_handle.handle); 3051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return handle; 3061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 30703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#if defined(USE_OZONE) 30803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) case gfx::OZONE_NATIVE_BUFFER: 30903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return source_handle; 31003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#endif 311a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#if defined(OS_MACOSX) 312a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) case gfx::IO_SURFACE_BUFFER: 313a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return source_handle; 314a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#endif 3154ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch#if defined(OS_ANDROID) 3164ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch case gfx::SURFACE_TEXTURE_BUFFER: 3174ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch return source_handle; 3184ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch#endif 3195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if defined(USE_X11) 3205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case gfx::X11_PIXMAP_BUFFER: 3215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return source_handle; 3225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif 3231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) default: 3241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) NOTREACHED(); 3251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return gfx::GpuMemoryBufferHandle(); 3261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 3271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 3281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)int32 GpuChannelHost::ReserveGpuMemoryBufferId() { 3301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return next_gpu_memory_buffer_id_.GetNext(); 3311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 3321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 333c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochint32 GpuChannelHost::GenerateRouteID() { 334c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return next_route_id_.GetNext(); 335c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 336c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 3377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)GpuChannelHost::~GpuChannelHost() { 3387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // channel_ must be destroyed on the main thread. 3397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!factory_->IsMainThread()) 3407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) factory_->GetMainLoop()->DeleteSoon(FROM_HERE, channel_.release()); 3417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)GpuChannelHost::MessageFilter::MessageFilter() 3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : lost_(false) { 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GpuChannelHost::MessageFilter::~MessageFilter() {} 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelHost::MessageFilter::AddRoute( 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int route_id, 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WeakPtr<IPC::Listener> listener, 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<MessageLoopProxy> loop) { 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(listeners_.find(route_id) == listeners_.end()); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GpuListenerInfo info; 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info.listener = listener; 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info.loop = loop; 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listeners_[route_id] = info; 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelHost::MessageFilter::RemoveRoute(int route_id) { 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ListenerMap::iterator it = listeners_.find(route_id); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (it != listeners_.end()) 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listeners_.erase(it); 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GpuChannelHost::MessageFilter::OnMessageReceived( 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const IPC::Message& message) { 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Never handle sync message replies or we will deadlock here. 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (message.is_reply()) 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ListenerMap::iterator it = listeners_.find(message.routing_id()); 3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (it == listeners_.end()) 3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const GpuListenerInfo& info = it->second; 3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) info.loop->PostTask( 3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FROM_HERE, 3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind( 3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::IgnoreResult(&IPC::Listener::OnMessageReceived), 3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) info.listener, 3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) message)); 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelHost::MessageFilter::OnChannelError() { 3887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Set the lost state before signalling the proxies. That way, if they 3897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // themselves post a task to recreate the context, they will not try to re-use 3907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // this channel host. 3917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) { 3927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) AutoLock lock(lock_); 3937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) lost_ = true; 3947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 3957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Inform all the proxies that an error has occurred. This will be reported 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // via OpenGL as a lost context. 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ListenerMap::iterator it = listeners_.begin(); 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != listeners_.end(); 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it++) { 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GpuListenerInfo& info = it->second; 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info.loop->PostTask( 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&IPC::Listener::OnChannelError, info.listener)); 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listeners_.clear(); 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool GpuChannelHost::MessageFilter::IsLost() const { 4117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) AutoLock lock(lock_); 4127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return lost_; 4137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 4147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content 416