gpu_channel_host.cc revision 7dbb3d5cf0c15f500944d211057644d6a2f37371
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"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/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"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "gpu/command_buffer/common/mailbox.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_sync_message_filter.h"
197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/common/sandbox_init.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::AutoLock;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::MessageLoopProxy;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GpuListenerInfo::GpuListenerInfo() {}
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GpuListenerInfo::~GpuListenerInfo() {}
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// static
357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)scoped_refptr<GpuChannelHost> GpuChannelHost::Create(
367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    GpuChannelHostFactory* factory,
377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    int gpu_host_id,
387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    int client_id,
397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const gpu::GPUInfo& gpu_info,
407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const IPC::ChannelHandle& channel_handle) {
417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK(factory->IsMainThread());
427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_refptr<GpuChannelHost> host = new GpuChannelHost(
437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      factory, gpu_host_id, client_id, gpu_info);
447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  host->Connect(channel_handle);
457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return host;
467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)GpuChannelHost::GpuChannelHost(GpuChannelHostFactory* factory,
497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               int gpu_host_id,
507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               int client_id,
517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               const gpu::GPUInfo& gpu_info)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : factory_(factory),
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      client_id_(client_id),
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gpu_host_id_(gpu_host_id),
557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      gpu_info_(gpu_info) {
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  next_transfer_buffer_id_.GetNext();
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void GpuChannelHost::Connect(const IPC::ChannelHandle& channel_handle) {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Open a channel to the GPU process. We pass NULL as the main listener here
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // since we need to filter everything to route it to the right thread.
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<base::MessageLoopProxy> io_loop = factory_->GetIOLoopProxy();
63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  channel_.reset(new IPC::SyncChannel(channel_handle,
64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                      IPC::Channel::MODE_CLIENT,
65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                      NULL,
66868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                      io_loop.get(),
67868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                      true,
68868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                      factory_->GetShutDownEvent()));
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_filter_ = new IPC::SyncMessageFilter(
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      factory_->GetShutDownEvent());
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  channel_->AddFilter(sync_filter_.get());
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  channel_filter_ = new MessageFilter();
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Install the filter last, because we intercept all leftover
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // messages.
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  channel_->AddFilter(channel_filter_.get());
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool GpuChannelHost::Send(IPC::Message* msg) {
837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Callee takes ownership of message, regardless of whether Send is
847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // successful. See IPC::Sender.
857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<IPC::Message> message(msg);
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The GPU process never sends synchronous IPCs so clear the unblock flag to
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // preserve order.
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message->set_unblock(false);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Currently we need to choose between two different mechanisms for sending.
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // On the main thread we use the regular channel Send() method, on another
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // thread we use SyncMessageFilter. We also have to be careful interpreting
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // IsMainThread() since it might return false during shutdown,
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // impl we are actually calling from the main thread (discard message then).
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO: Can we just always use sync_filter_ since we setup the channel
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //       without a main listener?
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (factory_->IsMainThread()) {
997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // http://crbug.com/125264
1007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    base::ThreadRestrictions::ScopedAllowWait allow_wait;
1017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return channel_->Send(message.release());
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else if (base::MessageLoop::current()) {
1037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return sync_filter_->Send(message.release());
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CommandBufferProxyImpl* GpuChannelHost::CreateViewCommandBuffer(
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int32 surface_id,
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CommandBufferProxyImpl* share_group,
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& allowed_extensions,
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::vector<int32>& attribs,
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& active_url,
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::GpuPreference gpu_preference) {
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TRACE_EVENT1("gpu",
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               "GpuChannelHost::CreateViewCommandBuffer",
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               "surface_id",
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               surface_id);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GPUCreateCommandBufferConfig init_params;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  init_params.share_group_id =
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      share_group ? share_group->GetRouteID() : MSG_ROUTING_NONE;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  init_params.allowed_extensions = allowed_extensions;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  init_params.attribs = attribs;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  init_params.active_url = active_url;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  init_params.gpu_preference = gpu_preference;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32 route_id = factory_->CreateViewCommandBuffer(surface_id, init_params);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (route_id == MSG_ROUTING_NONE)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CommandBufferProxyImpl* command_buffer =
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new CommandBufferProxyImpl(this, route_id);
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddRoute(route_id, command_buffer->AsWeakPtr());
1357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  AutoLock lock(context_lock_);
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  proxies_[route_id] = command_buffer;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return command_buffer;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CommandBufferProxyImpl* GpuChannelHost::CreateOffscreenCommandBuffer(
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Size& size,
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CommandBufferProxyImpl* share_group,
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& allowed_extensions,
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::vector<int32>& attribs,
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& active_url,
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::GpuPreference gpu_preference) {
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TRACE_EVENT0("gpu", "GpuChannelHost::CreateOffscreenCommandBuffer");
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GPUCreateCommandBufferConfig init_params;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  init_params.share_group_id =
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      share_group ? share_group->GetRouteID() : MSG_ROUTING_NONE;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  init_params.allowed_extensions = allowed_extensions;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  init_params.attribs = attribs;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  init_params.active_url = active_url;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  init_params.gpu_preference = gpu_preference;
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32 route_id;
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!Send(new GpuChannelMsg_CreateOffscreenCommandBuffer(size,
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                           init_params,
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                           &route_id))) {
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (route_id == MSG_ROUTING_NONE)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CommandBufferProxyImpl* command_buffer =
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new CommandBufferProxyImpl(this, route_id);
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddRoute(route_id, command_buffer->AsWeakPtr());
1707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  AutoLock lock(context_lock_);
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  proxies_[route_id] = command_buffer;
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return command_buffer;
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)scoped_ptr<media::VideoDecodeAccelerator> GpuChannelHost::CreateVideoDecoder(
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int command_buffer_route_id,
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    media::VideoCodecProfile profile,
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    media::VideoDecodeAccelerator::Client* client) {
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AutoLock lock(context_lock_);
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyMap::iterator it = proxies_.find(command_buffer_route_id);
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(it != proxies_.end());
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CommandBufferProxyImpl* proxy = it->second;
184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return proxy->CreateVideoDecoder(profile, client).Pass();
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelHost::DestroyCommandBuffer(
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CommandBufferProxyImpl* command_buffer) {
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TRACE_EVENT0("gpu", "GpuChannelHost::DestroyCommandBuffer");
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int route_id = command_buffer->GetRouteID();
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Send(new GpuChannelMsg_DestroyCommandBuffer(route_id));
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RemoveRoute(route_id);
1947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  AutoLock lock(context_lock_);
1967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  proxies_.erase(route_id);
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete command_buffer;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GpuChannelHost::CollectRenderingStatsForSurface(
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int surface_id, GpuRenderingStats* stats) {
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TRACE_EVENT0("gpu", "GpuChannelHost::CollectRenderingStats");
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Send(new GpuChannelMsg_CollectRenderingStatsForSurface(surface_id,
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                                stats));
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelHost::AddRoute(
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int route_id, base::WeakPtr<IPC::Listener> listener) {
2107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK(MessageLoopProxy::current().get());
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<base::MessageLoopProxy> io_loop = factory_->GetIOLoopProxy();
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  io_loop->PostTask(FROM_HERE,
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    base::Bind(&GpuChannelHost::MessageFilter::AddRoute,
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               channel_filter_.get(), route_id, listener,
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               MessageLoopProxy::current()));
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelHost::RemoveRoute(int route_id) {
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<base::MessageLoopProxy> io_loop = factory_->GetIOLoopProxy();
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  io_loop->PostTask(FROM_HERE,
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    base::Bind(&GpuChannelHost::MessageFilter::RemoveRoute,
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               channel_filter_.get(), route_id));
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::SharedMemoryHandle GpuChannelHost::ShareToGpuProcess(
227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    base::SharedMemoryHandle source_handle) {
2287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (IsLost())
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return base::SharedMemory::NULLHandle();
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Windows needs to explicitly duplicate the handle out to another process.
233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::SharedMemoryHandle target_handle;
234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!BrokerDuplicateHandle(source_handle,
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             channel_->peer_pid(),
236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             &target_handle,
237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             0,
238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             DUPLICATE_SAME_ACCESS)) {
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return base::SharedMemory::NULLHandle();
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return target_handle;
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int duped_handle = HANDLE_EINTR(dup(source_handle.fd));
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (duped_handle < 0)
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return base::SharedMemory::NULLHandle();
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return base::FileDescriptor(duped_handle, true);
249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GpuChannelHost::GenerateMailboxNames(unsigned num,
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          std::vector<gpu::Mailbox>* names) {
2547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK(names->empty());
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TRACE_EVENT0("gpu", "GenerateMailboxName");
2567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  size_t generate_count = channel_filter_->GetMailboxNames(num, names);
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (names->size() < num) {
2597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    std::vector<gpu::Mailbox> new_names;
2607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (!Send(new GpuChannelMsg_GenerateMailboxNames(num - names->size(),
2617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                                     &new_names)))
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
2637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    names->insert(names->end(), new_names.begin(), new_names.end());
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (generate_count > 0)
2677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    Send(new GpuChannelMsg_GenerateMailboxNamesAsync(generate_count));
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32 GpuChannelHost::ReserveTransferBufferId() {
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return next_transfer_buffer_id_.GetNext();
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)GpuChannelHost::~GpuChannelHost() {
2777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // channel_ must be destroyed on the main thread.
2787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!factory_->IsMainThread())
2797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    factory_->GetMainLoop()->DeleteSoon(FROM_HERE, channel_.release());
2807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)GpuChannelHost::MessageFilter::MessageFilter()
2847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    : lost_(false),
2857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      requested_mailboxes_(0) {
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GpuChannelHost::MessageFilter::~MessageFilter() {}
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelHost::MessageFilter::AddRoute(
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int route_id,
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::WeakPtr<IPC::Listener> listener,
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<MessageLoopProxy> loop) {
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(listeners_.find(route_id) == listeners_.end());
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GpuListenerInfo info;
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info.listener = listener;
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info.loop = loop;
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  listeners_[route_id] = info;
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelHost::MessageFilter::RemoveRoute(int route_id) {
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ListenerMap::iterator it = listeners_.find(route_id);
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (it != listeners_.end())
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    listeners_.erase(it);
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GpuChannelHost::MessageFilter::OnMessageReceived(
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const IPC::Message& message) {
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Never handle sync message replies or we will deadlock here.
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (message.is_reply())
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (message.routing_id() == MSG_ROUTING_CONTROL)
3147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return OnControlMessageReceived(message);
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ListenerMap::iterator it = listeners_.find(message.routing_id());
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (it != listeners_.end()) {
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GpuListenerInfo& info = it->second;
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    info.loop->PostTask(
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            base::IgnoreResult(&IPC::Listener::OnMessageReceived),
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            info.listener,
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            message));
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelHost::MessageFilter::OnChannelError() {
3327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Set the lost state before signalling the proxies. That way, if they
3337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // themselves post a task to recreate the context, they will not try to re-use
3347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // this channel host.
3357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  {
3367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    AutoLock lock(lock_);
3377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    lost_ = true;
3387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
3397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Inform all the proxies that an error has occurred. This will be reported
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // via OpenGL as a lost context.
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ListenerMap::iterator it = listeners_.begin();
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it != listeners_.end();
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it++) {
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GpuListenerInfo& info = it->second;
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    info.loop->PostTask(
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&IPC::Listener::OnChannelError, info.listener));
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  listeners_.clear();
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool GpuChannelHost::MessageFilter::IsLost() const {
3557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  AutoLock lock(lock_);
3567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return lost_;
3577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
3587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)size_t GpuChannelHost::MessageFilter::GetMailboxNames(
3607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    size_t num, std::vector<gpu::Mailbox>* names) {
3617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  AutoLock lock(lock_);
3627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  size_t count = std::min(num, mailbox_name_pool_.size());
3637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  names->insert(names->begin(),
3647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                mailbox_name_pool_.end() - count,
3657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                mailbox_name_pool_.end());
3667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  mailbox_name_pool_.erase(mailbox_name_pool_.end() - count,
3677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                           mailbox_name_pool_.end());
3687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  const size_t ideal_mailbox_pool_size = 100;
3707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  size_t total = mailbox_name_pool_.size() + requested_mailboxes_;
3717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK_LE(total, ideal_mailbox_pool_size);
3727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (total >= ideal_mailbox_pool_size / 2)
3737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return 0;
3747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  size_t request = ideal_mailbox_pool_size - total;
3757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  requested_mailboxes_ += request;
3767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return request;
3777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
3787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool GpuChannelHost::MessageFilter::OnControlMessageReceived(
3807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const IPC::Message& message) {
3817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool handled = true;
3827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  IPC_BEGIN_MESSAGE_MAP(GpuChannelHost::MessageFilter, message)
3847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  IPC_MESSAGE_HANDLER(GpuChannelMsg_GenerateMailboxNamesReply,
3857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                      OnGenerateMailboxNamesReply)
3867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  IPC_MESSAGE_UNHANDLED(handled = false)
3877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  IPC_END_MESSAGE_MAP()
3887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK(handled);
3907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return handled;
3917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
3927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void GpuChannelHost::MessageFilter::OnGenerateMailboxNamesReply(
3947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const std::vector<gpu::Mailbox>& names) {
3957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  TRACE_EVENT0("gpu", "OnGenerateMailboxNamesReply");
3967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  AutoLock lock(lock_);
3977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK_LE(names.size(), requested_mailboxes_);
3987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  requested_mailboxes_ -= names.size();
3997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  mailbox_name_pool_.insert(mailbox_name_pool_.end(),
4007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                            names.begin(),
4017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                            names.end());
4027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
4037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
406