summaryrefslogtreecommitdiffstats
path: root/content/browser/gpu_process_host.h
blob: 3ced7a6e802e8be009ecb42c2bdcb3be3f73ec2d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
// Copyright (c) 2011 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_PROCESS_HOST_H_
#define CONTENT_BROWSER_GPU_PROCESS_HOST_H_
#pragma once

#include <map>
#include <queue>

#include "base/callback.h"
#include "base/memory/linked_ptr.h"
#include "base/threading/non_thread_safe.h"
#include "content/browser/browser_child_process_host.h"
#include "content/common/gpu/gpu_info.h"
#include "content/common/gpu/gpu_process_launch_causes.h"
#include "ui/gfx/native_widget_types.h"

struct GPUCreateCommandBufferConfig;

namespace IPC {
class Message;
}

class GpuProcessHost : public BrowserChildProcessHost,
                       public base::NonThreadSafe {
 public:
  // Creates a new GpuProcessHost or gets one for a particular
  // renderer process, 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. A renderer ID of zero means the browser process.
  // This could return NULL if GPU access is not allowed (blacklisted).
  static GpuProcessHost* GetForRenderer(int renderer_id,
                                        content::CauseForGpuLaunch cause);

  // Helper function to send the given message to the GPU process on the IO
  // thread.  Calls GetForRenderer and if a host is returned, sends it.
  // Can be called from any thread.
  static void SendOnIO(int renderer_id,
                       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_; }

  virtual bool Send(IPC::Message* msg);

  // ChildProcessHost implementation.
  virtual bool OnMessageReceived(const IPC::Message& message);
  virtual void OnChannelConnected(int32 peer_pid);

  typedef Callback3<const IPC::ChannelHandle&,
                    base::ProcessHandle,
                    const GPUInfo&>::Type
    EstablishChannelCallback;

  // Tells the GPU process to create a new channel for communication with a
  // renderer. Once the GPU process responds asynchronously with the IPC handle
  // and GPUInfo, we call the callback.
  void EstablishGpuChannel(
      int renderer_id, EstablishChannelCallback* callback);

  typedef Callback0::Type SynchronizeCallback;

  // Sends a reply message later when the next GpuHostMsg_SynchronizeReply comes
  // in.
  void Synchronize(SynchronizeCallback* callback);

  typedef Callback1<int32>::Type CreateCommandBufferCallback;

  // Tells the GPU process to create a new command buffer that draws into the
  // window associated with the given renderer.
  void CreateViewCommandBuffer(
      gfx::PluginWindowHandle compositing_surface,
      int32 render_view_id,
      int32 renderer_id,
      const GPUCreateCommandBufferConfig& init_params,
      CreateCommandBufferCallback* callback);

 private:
  GpuProcessHost(int host_id);
  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);

  virtual bool CanShutdown();
  virtual void OnProcessLaunched();
  virtual void OnChildDied();
  virtual void OnProcessCrashed(int exit_code);

  // Message handlers.
  void OnChannelEstablished(const IPC::ChannelHandle& channel_handle);
  void OnSynchronizeReply();
  void OnCommandBufferCreated(const int32 route_id);
  void OnDestroyCommandBuffer(
      gfx::PluginWindowHandle window, int32 renderer_id, int32 render_view_id);
  void OnGraphicsInfoCollected(const GPUInfo& gpu_info);

  bool LaunchGpuProcess();

  void SendOutstandingReplies();
  void EstablishChannelError(
      EstablishChannelCallback* callback,
      const IPC::ChannelHandle& channel_handle,
      base::ProcessHandle renderer_process_for_gpu,
      const GPUInfo& gpu_info);
  void CreateCommandBufferError(CreateCommandBufferCallback* callback,
                                int32 route_id);
  void SynchronizeError(SynchronizeCallback* callback);

  // 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<linked_ptr<EstablishChannelCallback> > channel_requests_;

  // The pending synchronization requests we need to reply to.
  std::queue<linked_ptr<SynchronizeCallback> > synchronize_requests_;

  // The pending create command buffer requests we need to reply to.
  std::queue<linked_ptr<CreateCommandBufferCallback> >
      create_command_buffer_requests_;

#if defined(OS_LINUX)
  typedef std::pair<int32 /* renderer_id */,
                    int32 /* render_view_id */> ViewID;

  // 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<ViewID, linked_ptr<SurfaceRef> > SurfaceRefMap;
  SurfaceRefMap surface_refs_;
#endif

  // Qeueud messages to send when the process launches.
  std::queue<IPC::Message*> queued_messages_;

  // The handle for the GPU process or null if it is not known to be launched.
  base::ProcessHandle gpu_process_;

  DISALLOW_COPY_AND_ASSIGN(GpuProcessHost);
};

#endif  // CONTENT_BROWSER_GPU_PROCESS_HOST_H_