gpu_channel_host.cc revision 1e9bf3e0803691d0a228da41fc608347b6db4340
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"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "gpu/command_buffer/common/mailbox.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_sync_message_filter.h"
207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/common/sandbox_init.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::AutoLock;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::MessageLoopProxy;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GpuListenerInfo::GpuListenerInfo() {}
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GpuListenerInfo::~GpuListenerInfo() {}
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// static
367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)scoped_refptr<GpuChannelHost> GpuChannelHost::Create(
377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    GpuChannelHostFactory* factory,
387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    int gpu_host_id,
397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    int client_id,
407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const gpu::GPUInfo& gpu_info,
417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const IPC::ChannelHandle& channel_handle) {
427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK(factory->IsMainThread());
437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_refptr<GpuChannelHost> host = new GpuChannelHost(
447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      factory, gpu_host_id, client_id, gpu_info);
457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  host->Connect(channel_handle);
467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return host;
477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// static
501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)bool GpuChannelHost::IsValidGpuMemoryBuffer(
511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    gfx::GpuMemoryBufferHandle handle) {
521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  switch (handle.type) {
531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    case gfx::SHARED_MEMORY_BUFFER:
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)                               int gpu_host_id,
627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               int client_id,
637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               const gpu::GPUInfo& gpu_info)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : factory_(factory),
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      client_id_(client_id),
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gpu_host_id_(gpu_host_id),
677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      gpu_info_(gpu_info) {
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  next_transfer_buffer_id_.GetNext();
691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  next_gpu_memory_buffer_id_.GetNext();
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void GpuChannelHost::Connect(const IPC::ChannelHandle& channel_handle) {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Open a channel to the GPU process. We pass NULL as the main listener here
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // since we need to filter everything to route it to the right thread.
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<base::MessageLoopProxy> io_loop = factory_->GetIOLoopProxy();
76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  channel_.reset(new IPC::SyncChannel(channel_handle,
77868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                      IPC::Channel::MODE_CLIENT,
78868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                      NULL,
79868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                      io_loop.get(),
80868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                      true,
81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                      factory_->GetShutDownEvent()));
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_filter_ = new IPC::SyncMessageFilter(
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      factory_->GetShutDownEvent());
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  channel_->AddFilter(sync_filter_.get());
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  channel_filter_ = new MessageFilter();
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Install the filter last, because we intercept all leftover
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // messages.
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  channel_->AddFilter(channel_filter_.get());
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool GpuChannelHost::Send(IPC::Message* msg) {
967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Callee takes ownership of message, regardless of whether Send is
977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // successful. See IPC::Sender.
987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<IPC::Message> message(msg);
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The GPU process never sends synchronous IPCs so clear the unblock flag to
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // preserve order.
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message->set_unblock(false);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Currently we need to choose between two different mechanisms for sending.
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // On the main thread we use the regular channel Send() method, on another
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // thread we use SyncMessageFilter. We also have to be careful interpreting
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // IsMainThread() since it might return false during shutdown,
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // impl we are actually calling from the main thread (discard message then).
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO: Can we just always use sync_filter_ since we setup the channel
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //       without a main listener?
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (factory_->IsMainThread()) {
1127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // http://crbug.com/125264
1137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    base::ThreadRestrictions::ScopedAllowWait allow_wait;
1147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return channel_->Send(message.release());
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else if (base::MessageLoop::current()) {
1167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return sync_filter_->Send(message.release());
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CommandBufferProxyImpl* GpuChannelHost::CreateViewCommandBuffer(
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int32 surface_id,
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CommandBufferProxyImpl* share_group,
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::vector<int32>& attribs,
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& active_url,
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::GpuPreference gpu_preference) {
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TRACE_EVENT1("gpu",
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               "GpuChannelHost::CreateViewCommandBuffer",
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               "surface_id",
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               surface_id);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GPUCreateCommandBufferConfig init_params;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  init_params.share_group_id =
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      share_group ? share_group->GetRouteID() : MSG_ROUTING_NONE;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  init_params.attribs = attribs;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  init_params.active_url = active_url;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  init_params.gpu_preference = gpu_preference;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32 route_id = factory_->CreateViewCommandBuffer(surface_id, init_params);
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (route_id == MSG_ROUTING_NONE)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CommandBufferProxyImpl* command_buffer =
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new CommandBufferProxyImpl(this, route_id);
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddRoute(route_id, command_buffer->AsWeakPtr());
1467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  AutoLock lock(context_lock_);
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  proxies_[route_id] = command_buffer;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return command_buffer;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CommandBufferProxyImpl* GpuChannelHost::CreateOffscreenCommandBuffer(
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Size& size,
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CommandBufferProxyImpl* share_group,
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::vector<int32>& attribs,
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& active_url,
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::GpuPreference gpu_preference) {
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TRACE_EVENT0("gpu", "GpuChannelHost::CreateOffscreenCommandBuffer");
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GPUCreateCommandBufferConfig init_params;
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  init_params.share_group_id =
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      share_group ? share_group->GetRouteID() : MSG_ROUTING_NONE;
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  init_params.attribs = attribs;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  init_params.active_url = active_url;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  init_params.gpu_preference = gpu_preference;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32 route_id;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!Send(new GpuChannelMsg_CreateOffscreenCommandBuffer(size,
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                           init_params,
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                           &route_id))) {
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (route_id == MSG_ROUTING_NONE)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CommandBufferProxyImpl* command_buffer =
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new CommandBufferProxyImpl(this, route_id);
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddRoute(route_id, command_buffer->AsWeakPtr());
1797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  AutoLock lock(context_lock_);
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  proxies_[route_id] = command_buffer;
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return command_buffer;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)scoped_ptr<media::VideoDecodeAccelerator> GpuChannelHost::CreateVideoDecoder(
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int command_buffer_route_id,
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    media::VideoCodecProfile profile,
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    media::VideoDecodeAccelerator::Client* client) {
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AutoLock lock(context_lock_);
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyMap::iterator it = proxies_.find(command_buffer_route_id);
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(it != proxies_.end());
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CommandBufferProxyImpl* proxy = it->second;
193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return proxy->CreateVideoDecoder(profile, client).Pass();
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)scoped_ptr<media::VideoEncodeAccelerator> GpuChannelHost::CreateVideoEncoder(
1973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    media::VideoEncodeAccelerator::Client* client) {
1983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  TRACE_EVENT0("gpu", "GpuChannelHost::CreateVideoEncoder");
1993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<media::VideoEncodeAccelerator> vea;
2013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  int32 route_id = MSG_ROUTING_NONE;
2023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!Send(new GpuChannelMsg_CreateVideoEncoder(&route_id)))
2033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return vea.Pass();
2043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (route_id == MSG_ROUTING_NONE)
2053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return vea.Pass();
2063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  vea.reset(new GpuVideoEncodeAcceleratorHost(client, this, route_id));
2083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return vea.Pass();
2093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
2103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelHost::DestroyCommandBuffer(
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CommandBufferProxyImpl* command_buffer) {
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TRACE_EVENT0("gpu", "GpuChannelHost::DestroyCommandBuffer");
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int route_id = command_buffer->GetRouteID();
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Send(new GpuChannelMsg_DestroyCommandBuffer(route_id));
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RemoveRoute(route_id);
2187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  AutoLock lock(context_lock_);
2207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  proxies_.erase(route_id);
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete command_buffer;
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GpuChannelHost::CollectRenderingStatsForSurface(
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int surface_id, GpuRenderingStats* stats) {
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TRACE_EVENT0("gpu", "GpuChannelHost::CollectRenderingStats");
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Send(new GpuChannelMsg_CollectRenderingStatsForSurface(surface_id,
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                                stats));
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelHost::AddRoute(
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int route_id, base::WeakPtr<IPC::Listener> listener) {
2347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK(MessageLoopProxy::current().get());
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<base::MessageLoopProxy> io_loop = factory_->GetIOLoopProxy();
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  io_loop->PostTask(FROM_HERE,
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    base::Bind(&GpuChannelHost::MessageFilter::AddRoute,
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               channel_filter_.get(), route_id, listener,
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               MessageLoopProxy::current()));
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelHost::RemoveRoute(int route_id) {
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<base::MessageLoopProxy> io_loop = factory_->GetIOLoopProxy();
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  io_loop->PostTask(FROM_HERE,
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    base::Bind(&GpuChannelHost::MessageFilter::RemoveRoute,
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               channel_filter_.get(), route_id));
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::SharedMemoryHandle GpuChannelHost::ShareToGpuProcess(
251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    base::SharedMemoryHandle source_handle) {
2527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (IsLost())
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return base::SharedMemory::NULLHandle();
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Windows needs to explicitly duplicate the handle out to another process.
257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::SharedMemoryHandle target_handle;
258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!BrokerDuplicateHandle(source_handle,
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             channel_->peer_pid(),
260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             &target_handle,
261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             0,
262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             DUPLICATE_SAME_ACCESS)) {
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return base::SharedMemory::NULLHandle();
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return target_handle;
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int duped_handle = HANDLE_EINTR(dup(source_handle.fd));
269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (duped_handle < 0)
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return base::SharedMemory::NULLHandle();
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return base::FileDescriptor(duped_handle, true);
273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GpuChannelHost::GenerateMailboxNames(unsigned num,
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          std::vector<gpu::Mailbox>* names) {
2787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK(names->empty());
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TRACE_EVENT0("gpu", "GenerateMailboxName");
2807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  size_t generate_count = channel_filter_->GetMailboxNames(num, names);
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (names->size() < num) {
2837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    std::vector<gpu::Mailbox> new_names;
2847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (!Send(new GpuChannelMsg_GenerateMailboxNames(num - names->size(),
2857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                                     &new_names)))
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
2877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    names->insert(names->end(), new_names.begin(), new_names.end());
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (generate_count > 0)
2917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    Send(new GpuChannelMsg_GenerateMailboxNamesAsync(generate_count));
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32 GpuChannelHost::ReserveTransferBufferId() {
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return next_transfer_buffer_id_.GetNext();
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)gfx::GpuMemoryBufferHandle GpuChannelHost::ShareGpuMemoryBufferToGpuProcess(
3011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    gfx::GpuMemoryBufferHandle source_handle) {
3021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  switch (source_handle.type) {
3031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    case gfx::SHARED_MEMORY_BUFFER: {
3041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      gfx::GpuMemoryBufferHandle handle;
3051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      handle.type = gfx::SHARED_MEMORY_BUFFER;
3061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      handle.handle = ShareToGpuProcess(source_handle.handle);
3071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      return handle;
3081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    }
3091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    default:
3101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      NOTREACHED();
3111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      return gfx::GpuMemoryBufferHandle();
3121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
3131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
3141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)int32 GpuChannelHost::ReserveGpuMemoryBufferId() {
3161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return next_gpu_memory_buffer_id_.GetNext();
3171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
3181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)GpuChannelHost::~GpuChannelHost() {
3207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // channel_ must be destroyed on the main thread.
3217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!factory_->IsMainThread())
3227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    factory_->GetMainLoop()->DeleteSoon(FROM_HERE, channel_.release());
3237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)GpuChannelHost::MessageFilter::MessageFilter()
3277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    : lost_(false),
3287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      requested_mailboxes_(0) {
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GpuChannelHost::MessageFilter::~MessageFilter() {}
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelHost::MessageFilter::AddRoute(
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int route_id,
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::WeakPtr<IPC::Listener> listener,
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<MessageLoopProxy> loop) {
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(listeners_.find(route_id) == listeners_.end());
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GpuListenerInfo info;
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info.listener = listener;
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info.loop = loop;
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  listeners_[route_id] = info;
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelHost::MessageFilter::RemoveRoute(int route_id) {
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ListenerMap::iterator it = listeners_.find(route_id);
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (it != listeners_.end())
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    listeners_.erase(it);
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GpuChannelHost::MessageFilter::OnMessageReceived(
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const IPC::Message& message) {
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Never handle sync message replies or we will deadlock here.
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (message.is_reply())
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (message.routing_id() == MSG_ROUTING_CONTROL)
3577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return OnControlMessageReceived(message);
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ListenerMap::iterator it = listeners_.find(message.routing_id());
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (it != listeners_.end()) {
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GpuListenerInfo& info = it->second;
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    info.loop->PostTask(
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            base::IgnoreResult(&IPC::Listener::OnMessageReceived),
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            info.listener,
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            message));
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelHost::MessageFilter::OnChannelError() {
3757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Set the lost state before signalling the proxies. That way, if they
3767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // themselves post a task to recreate the context, they will not try to re-use
3777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // this channel host.
3787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  {
3797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    AutoLock lock(lock_);
3807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    lost_ = true;
3817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
3827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Inform all the proxies that an error has occurred. This will be reported
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // via OpenGL as a lost context.
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ListenerMap::iterator it = listeners_.begin();
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it != listeners_.end();
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it++) {
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GpuListenerInfo& info = it->second;
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    info.loop->PostTask(
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&IPC::Listener::OnChannelError, info.listener));
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  listeners_.clear();
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool GpuChannelHost::MessageFilter::IsLost() const {
3987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  AutoLock lock(lock_);
3997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return lost_;
4007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
4017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)size_t GpuChannelHost::MessageFilter::GetMailboxNames(
4037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    size_t num, std::vector<gpu::Mailbox>* names) {
4047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  AutoLock lock(lock_);
4057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  size_t count = std::min(num, mailbox_name_pool_.size());
4067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  names->insert(names->begin(),
4077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                mailbox_name_pool_.end() - count,
4087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                mailbox_name_pool_.end());
4097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  mailbox_name_pool_.erase(mailbox_name_pool_.end() - count,
4107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                           mailbox_name_pool_.end());
4117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  const size_t ideal_mailbox_pool_size = 100;
4137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  size_t total = mailbox_name_pool_.size() + requested_mailboxes_;
4147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK_LE(total, ideal_mailbox_pool_size);
4157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (total >= ideal_mailbox_pool_size / 2)
4167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return 0;
4177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  size_t request = ideal_mailbox_pool_size - total;
4187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  requested_mailboxes_ += request;
4197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return request;
4207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
4217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool GpuChannelHost::MessageFilter::OnControlMessageReceived(
4237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const IPC::Message& message) {
4247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool handled = true;
4257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  IPC_BEGIN_MESSAGE_MAP(GpuChannelHost::MessageFilter, message)
4277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  IPC_MESSAGE_HANDLER(GpuChannelMsg_GenerateMailboxNamesReply,
4287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                      OnGenerateMailboxNamesReply)
4297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  IPC_MESSAGE_UNHANDLED(handled = false)
4307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  IPC_END_MESSAGE_MAP()
4317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK(handled);
4337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return handled;
4347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
4357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void GpuChannelHost::MessageFilter::OnGenerateMailboxNamesReply(
4377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const std::vector<gpu::Mailbox>& names) {
4387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  TRACE_EVENT0("gpu", "OnGenerateMailboxNamesReply");
4397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  AutoLock lock(lock_);
4407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK_LE(names.size(), requested_mailboxes_);
4417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  requested_mailboxes_ -= names.size();
4427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  mailbox_name_pool_.insert(mailbox_name_pool_.end(),
4437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                            names.begin(),
4447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                            names.end());
4457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
4467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
449