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