blob: f101c6c3d4ff940708b24da479df589db44e1705 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_GPU_GPU_PROCESS_HOST_H_
#define CONTENT_BROWSER_GPU_GPU_PROCESS_HOST_H_
#pragma once
#include <map>
#include <queue>
#include <string>
#include "base/callback.h"
#include "base/memory/linked_ptr.h"
#include "base/process.h"
#include "base/threading/non_thread_safe.h"
#include "base/time.h"
#include "content/common/content_export.h"
#include "content/common/gpu/gpu_process_launch_causes.h"
#include "content/public/browser/browser_child_process_host_delegate.h"
#include "content/public/common/gpu_info.h"
#include "ipc/ipc_message.h"
#include "ui/gfx/native_widget_types.h"
class GpuMainThread;
struct GPUCreateCommandBufferConfig;
struct GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params;
struct GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params;
struct GpuHostMsg_AcceleratedSurfaceRelease_Params;
class BrowserChildProcessHostImpl;
class GpuProcessHost : public content::BrowserChildProcessHostDelegate,
public IPC::Message::Sender,
public base::NonThreadSafe {
public:
enum GpuProcessKind {
GPU_PROCESS_KIND_UNSANDBOXED,
GPU_PROCESS_KIND_SANDBOXED,
GPU_PROCESS_KIND_COUNT
};
typedef base::Callback<void(const IPC::ChannelHandle&,
const content::GPUInfo&)>
EstablishChannelCallback;
typedef base::Callback<void(int32)> CreateCommandBufferCallback;
static bool gpu_enabled() { return gpu_enabled_; }
// Creates a new GpuProcessHost or gets an existing one, resulting in the
// launching of a GPU process if required. Returns null on failure. It
// is not safe to store the pointer once control has returned to the message
// loop as it can be destroyed. Instead store the associated GPU host ID.
// This could return NULL if GPU access is not allowed (blacklisted).
static GpuProcessHost* Get(GpuProcessKind kind,
content::CauseForGpuLaunch cause);
// Helper function to send the given message to the GPU process on the IO
// thread. Calls Get and if a host is returned, sends it. Can be called from
// any thread.
CONTENT_EXPORT static void SendOnIO(GpuProcessKind kind,
content::CauseForGpuLaunch cause,
IPC::Message* message);
// Get the GPU process host for the GPU process with the given ID. Returns
// null if the process no longer exists.
static GpuProcessHost* FromID(int host_id);
int host_id() const { return host_id_; }
// IPC::Message::Sender implementation.
virtual bool Send(IPC::Message* msg) OVERRIDE;
// Tells the GPU process to create a new channel for communication with a
// client. Once the GPU process responds asynchronously with the IPC handle
// and GPUInfo, we call the callback.
void EstablishGpuChannel(int client_id,
bool share_context,
const EstablishChannelCallback& callback);
// Tells the GPU process to create a new command buffer that draws into the
// given surface.
void CreateViewCommandBuffer(
const gfx::GLSurfaceHandle& compositing_surface,
int surface_id,
int client_id,
const GPUCreateCommandBufferConfig& init_params,
const CreateCommandBufferCallback& callback);
// Whether this GPU process is set up to use software rendering.
bool software_rendering();
// What kind of GPU process, e.g. sandboxed or unsandboxed.
GpuProcessKind kind();
void ForceShutdown();
private:
static bool HostIsValid(GpuProcessHost* host);
GpuProcessHost(int host_id, GpuProcessKind kind);
virtual ~GpuProcessHost();
bool Init();
// Post an IPC message to the UI shim's message handler on the UI thread.
void RouteOnUIThread(const IPC::Message& message);
// BrowserChildProcessHostDelegate implementation.
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
virtual void OnChannelConnected(int32 peer_pid) OVERRIDE;
virtual void OnProcessLaunched() OVERRIDE;
virtual void OnProcessCrashed(int exit_code) OVERRIDE;
// Message handlers.
void OnChannelEstablished(const IPC::ChannelHandle& channel_handle);
void OnCommandBufferCreated(const int32 route_id);
void OnDestroyCommandBuffer(int32 surface_id);
#if defined(OS_WIN) && !defined(USE_AURA)
void OnAcceleratedSurfaceBuffersSwapped(
const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params);
void OnAcceleratedSurfacePostSubBuffer(
const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params);
void OnAcceleratedSurfaceSuspend(int32 surface_id);
void OnAcceleratedSurfaceRelease(
const GpuHostMsg_AcceleratedSurfaceRelease_Params& params);
#endif
bool LaunchGpuProcess(const std::string& channel_id);
void SendOutstandingReplies();
void EstablishChannelError(
const EstablishChannelCallback& callback,
const IPC::ChannelHandle& channel_handle,
base::ProcessHandle client_process_for_gpu,
const content::GPUInfo& gpu_info);
void CreateCommandBufferError(const CreateCommandBufferCallback& callback,
int32 route_id);
// The serial number of the GpuProcessHost / GpuProcessHostUIShim pair.
int host_id_;
// These are the channel requests that we have already sent to
// the GPU process, but haven't heard back about yet.
std::queue<EstablishChannelCallback> channel_requests_;
// The pending create command buffer requests we need to reply to.
std::queue<CreateCommandBufferCallback> create_command_buffer_requests_;
#if defined(TOOLKIT_GTK)
// Encapsulates surfaces that we lock when creating view command buffers.
// We release this lock once the command buffer (or associated GPU process)
// is destroyed. This prevents the browser from destroying the surface
// while the GPU process is drawing to it.
// Multimap is used to simulate reference counting, see comment in
// GpuProcessHostUIShim::CreateViewCommandBuffer.
class SurfaceRef;
typedef std::multimap<int, linked_ptr<SurfaceRef> > SurfaceRefMap;
SurfaceRefMap surface_refs_;
#endif
// Qeueud messages to send when the process launches.
std::queue<IPC::Message*> queued_messages_;
// Whether we are running a GPU thread inside the browser process instead
// of a separate GPU process.
bool in_process_;
bool software_rendering_;
GpuProcessKind kind_;
scoped_ptr<GpuMainThread> in_process_gpu_thread_;
// Whether we actually launched a GPU process.
bool process_launched_;
// Time Init started. Used to log total GPU process startup time to UMA.
base::TimeTicks init_start_time_;
// Master switch for enabling/disabling GPU acceleration for the current
// browser session. It does not change the acceleration settings for
// existing tabs, just the future ones.
static bool gpu_enabled_;
static bool hardware_gpu_enabled_;
scoped_ptr<BrowserChildProcessHostImpl> process_;
DISALLOW_COPY_AND_ASSIGN(GpuProcessHost);
};
#endif // CONTENT_BROWSER_GPU_GPU_PROCESS_HOST_H_