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/gpu_channel_manager.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/child/child_thread.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/gpu_channel.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/gpu_memory_manager.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/gpu_messages.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/sync_point_manager.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/feature_info.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/gpu_switches.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/mailbox_manager.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/memory_program_cache.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_bindings.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_share_group.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GpuChannelManager::ImageOperation::ImageOperation(
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int32 sync_point, base::Closure callback)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : sync_point(sync_point),
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback(callback) {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GpuChannelManager::ImageOperation::~ImageOperation() {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GpuChannelManager::GpuChannelManager(ChildThread* gpu_child_thread,
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     GpuWatchdog* watchdog,
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     base::MessageLoopProxy* io_message_loop,
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     base::WaitableEvent* shutdown_event)
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : weak_factory_(this),
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      io_message_loop_(io_message_loop),
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      shutdown_event_(shutdown_event),
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gpu_child_thread_(gpu_child_thread),
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      gpu_memory_manager_(
417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          this,
427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          GpuMemoryManager::kDefaultMaxSurfacesWithFrontbufferSoftLimit),
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      watchdog_(watchdog),
447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      sync_point_manager_(new SyncPointManager) {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(gpu_child_thread);
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(io_message_loop);
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(shutdown_event);
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GpuChannelManager::~GpuChannelManager() {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gpu_channels_.clear();
52868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (default_offscreen_surface_.get()) {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default_offscreen_surface_->Destroy();
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default_offscreen_surface_ = NULL;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(image_operations_.empty());
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gpu::gles2::ProgramCache* GpuChannelManager::program_cache() {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!program_cache_.get() &&
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (gfx::g_driver_gl.ext.b_ARB_get_program_binary ||
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       gfx::g_driver_gl.ext.b_OES_get_program_binary) &&
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !CommandLine::ForCurrentProcess()->HasSwitch(
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          switches::kDisableGpuProgramCache)) {
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    program_cache_.reset(new gpu::gles2::MemoryProgramCache());
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return program_cache_.get();
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelManager::RemoveChannel(int client_id) {
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Send(new GpuHostMsg_DestroyChannel(client_id));
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gpu_channels_.erase(client_id);
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int GpuChannelManager::GenerateRouteID() {
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static int last_id = 0;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ++last_id;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelManager::AddRoute(int32 routing_id, IPC::Listener* listener) {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gpu_child_thread_->AddRoute(routing_id, listener);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelManager::RemoveRoute(int32 routing_id) {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gpu_child_thread_->RemoveRoute(routing_id);
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GpuChannel* GpuChannelManager::LookupChannel(int32 client_id) {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GpuChannelMap::const_iterator iter = gpu_channels_.find(client_id);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (iter == gpu_channels_.end())
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
93868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return iter->second.get();
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GpuChannelManager::OnMessageReceived(const IPC::Message& msg) {
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool msg_is_ok = true;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool handled = true;
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_BEGIN_MESSAGE_MAP_EX(GpuChannelManager, msg, msg_is_ok)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(GpuMsg_EstablishChannel, OnEstablishChannel)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(GpuMsg_CloseChannel, OnCloseChannel)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(GpuMsg_CreateViewCommandBuffer,
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnCreateViewCommandBuffer)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(GpuMsg_CreateImage, OnCreateImage)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(GpuMsg_DeleteImage, OnDeleteImage)
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IPC_MESSAGE_HANDLER(GpuMsg_LoadedShader, OnLoadedShader)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_UNHANDLED(handled = false)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_END_MESSAGE_MAP_EX()
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return handled;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GpuChannelManager::Send(IPC::Message* msg) {
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return gpu_child_thread_->Send(msg);
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelManager::OnEstablishChannel(int client_id, bool share_context) {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC::ChannelHandle channel_handle;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::GLShareGroup* share_group = NULL;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gpu::gles2::MailboxManager* mailbox_manager = NULL;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (share_context) {
122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (!share_group_.get()) {
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      share_group_ = new gfx::GLShareGroup;
124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      DCHECK(!mailbox_manager_.get());
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mailbox_manager_ = new gpu::gles2::MailboxManager;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    share_group = share_group_.get();
128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    mailbox_manager = mailbox_manager_.get();
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<GpuChannel> channel = new GpuChannel(this,
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                     watchdog_,
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                     share_group,
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                     mailbox_manager,
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                     client_id,
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                     false);
137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (channel->Init(io_message_loop_.get(), shutdown_event_)) {
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gpu_channels_[client_id] = channel;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    channel_handle.name = channel->GetChannelName();
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // On POSIX, pass the renderer-side FD. Also mark it as auto-close so
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // that it gets closed after it has been sent.
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int renderer_fd = channel->TakeRendererFileDescriptor();
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK_NE(-1, renderer_fd);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    channel_handle.socket = base::FileDescriptor(renderer_fd, true);
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Send(new GpuHostMsg_ChannelEstablished(channel_handle));
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelManager::OnCloseChannel(
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const IPC::ChannelHandle& channel_handle) {
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (GpuChannelMap::iterator iter = gpu_channels_.begin();
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != gpu_channels_.end(); ++iter) {
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (iter->second->GetChannelName() == channel_handle.name) {
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gpu_channels_.erase(iter);
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelManager::OnCreateViewCommandBuffer(
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::GLSurfaceHandle& window,
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int32 surface_id,
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int32 client_id,
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GPUCreateCommandBufferConfig& init_params) {
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(surface_id);
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32 route_id = MSG_ROUTING_NONE;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GpuChannelMap::const_iterator iter = gpu_channels_.find(client_id);
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (iter != gpu_channels_.end()) {
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    iter->second->CreateViewCommandBuffer(
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        window, surface_id, init_params, &route_id);
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Send(new GpuHostMsg_CommandBufferCreated(route_id));
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelManager::CreateImage(
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::PluginWindowHandle window, int32 client_id, int32 image_id) {
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Size size;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GpuChannelMap::const_iterator iter = gpu_channels_.find(client_id);
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (iter != gpu_channels_.end()) {
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    iter->second->CreateImage(window, image_id, &size);
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Send(new GpuHostMsg_ImageCreated(size));
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelManager::OnCreateImage(
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::PluginWindowHandle window, int32 client_id, int32 image_id) {
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(image_id);
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (image_operations_.empty()) {
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateImage(window, client_id, image_id);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    image_operations_.push_back(
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new ImageOperation(0, base::Bind(&GpuChannelManager::CreateImage,
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         base::Unretained(this),
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         window,
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         client_id,
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         image_id)));
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelManager::DeleteImage(int32 client_id, int32 image_id) {
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GpuChannelMap::const_iterator iter = gpu_channels_.find(client_id);
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (iter != gpu_channels_.end()) {
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    iter->second->DeleteImage(image_id);
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelManager::OnDeleteImage(
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int32 client_id, int32 image_id, int32 sync_point) {
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(image_id);
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!sync_point && image_operations_.empty()) {
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DeleteImage(client_id, image_id);
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    image_operations_.push_back(
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new ImageOperation(sync_point,
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           base::Bind(&GpuChannelManager::DeleteImage,
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      base::Unretained(this),
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      client_id,
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      image_id)));
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sync_point) {
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sync_point_manager()->AddSyncPointCallback(
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          sync_point,
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::Bind(&GpuChannelManager::OnDeleteImageSyncPointRetired,
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     base::Unretained(this),
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     image_operations_.back()));
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelManager::OnDeleteImageSyncPointRetired(
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ImageOperation* image_operation) {
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Mark operation as no longer having a pending sync point.
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  image_operation->sync_point = 0;
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // De-queue operations until we reach a pending sync point.
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (!image_operations_.empty()) {
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Check if operation has a pending sync point.
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (image_operations_.front()->sync_point)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    image_operations_.front()->callback.Run();
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete image_operations_.front();
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    image_operations_.pop_front();
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GpuChannelManager::OnLoadedShader(std::string program_proto) {
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (program_cache())
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    program_cache()->LoadProgram(program_proto);
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuChannelManager::HandleMessagesScheduled() {
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (GpuChannelMap::iterator iter = gpu_channels_.begin();
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       iter != gpu_channels_.end(); ++iter) {
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (iter->second->handle_messages_scheduled())
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return true;
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)uint64 GpuChannelManager::MessagesProcessed() {
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uint64 messages_processed = 0;
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (GpuChannelMap::iterator iter = gpu_channels_.begin();
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       iter != gpu_channels_.end(); ++iter) {
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    messages_processed += iter->second->messages_processed();
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return messages_processed;
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelManager::LoseAllContexts() {
2817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  for (GpuChannelMap::iterator iter = gpu_channels_.begin();
2827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch       iter != gpu_channels_.end(); ++iter) {
2837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    iter->second->MarkAllContextsLost();
2847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop::current()->PostTask(
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&GpuChannelManager::OnLoseAllContexts,
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 weak_factory_.GetWeakPtr()));
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannelManager::OnLoseAllContexts() {
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gpu_channels_.clear();
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::GLSurface* GpuChannelManager::GetDefaultOffscreenSurface() {
296868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!default_offscreen_surface_.get()) {
297868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    default_offscreen_surface_ =
2987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size(1, 1));
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return default_offscreen_surface_.get();
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
304