gpu_channel_host.h revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CONTENT_COMMON_GPU_CLIENT_GPU_CHANNEL_HOST_H_
6#define CONTENT_COMMON_GPU_CLIENT_GPU_CHANNEL_HOST_H_
7
8#include <string>
9#include <vector>
10
11#include "base/atomic_sequence_num.h"
12#include "base/hash_tables.h"
13#include "base/memory/ref_counted.h"
14#include "base/memory/scoped_ptr.h"
15#include "base/memory/weak_ptr.h"
16#include "base/process.h"
17#include "base/process_util.h"
18#include "base/synchronization/lock.h"
19#include "content/common/content_export.h"
20#include "content/common/gpu/gpu_process_launch_causes.h"
21#include "content/common/message_router.h"
22#include "content/public/common/gpu_info.h"
23#include "ipc/ipc_channel_handle.h"
24#include "ipc/ipc_channel_proxy.h"
25#include "ipc/ipc_sync_channel.h"
26#include "media/video/video_decode_accelerator.h"
27#include "ui/gfx/native_widget_types.h"
28#include "ui/gfx/size.h"
29#include "ui/gl/gpu_preference.h"
30
31class GURL;
32class TransportTextureService;
33struct GPUCreateCommandBufferConfig;
34
35namespace base {
36class MessageLoop;
37class MessageLoopProxy;
38}
39
40namespace gpu {
41struct Mailbox;
42}
43
44namespace IPC {
45class SyncMessageFilter;
46}
47
48namespace content {
49class CommandBufferProxyImpl;
50class GpuChannelHost;
51struct GpuRenderingStats;
52
53struct GpuListenerInfo {
54  GpuListenerInfo();
55  ~GpuListenerInfo();
56
57  base::WeakPtr<IPC::Listener> listener;
58  scoped_refptr<base::MessageLoopProxy> loop;
59};
60
61class CONTENT_EXPORT GpuChannelHostFactory {
62 public:
63  typedef base::Callback<void(const gfx::Size)> CreateImageCallback;
64
65  virtual ~GpuChannelHostFactory() {}
66
67  virtual bool IsMainThread() = 0;
68  virtual bool IsIOThread() = 0;
69  virtual base::MessageLoop* GetMainLoop() = 0;
70  virtual scoped_refptr<base::MessageLoopProxy> GetIOLoopProxy() = 0;
71  virtual base::WaitableEvent* GetShutDownEvent() = 0;
72  virtual scoped_ptr<base::SharedMemory> AllocateSharedMemory(size_t size) = 0;
73  virtual int32 CreateViewCommandBuffer(
74      int32 surface_id, const GPUCreateCommandBufferConfig& init_params) = 0;
75  virtual GpuChannelHost* EstablishGpuChannelSync(CauseForGpuLaunch) = 0;
76  virtual void CreateImage(
77      gfx::PluginWindowHandle window,
78      int32 image_id,
79      const CreateImageCallback& callback) = 0;
80  virtual void DeleteImage(int32 image_id, int32 sync_point) = 0;
81};
82
83// Encapsulates an IPC channel between the client and one GPU process.
84// On the GPU process side there's a corresponding GpuChannel.
85class GpuChannelHost : public IPC::Sender,
86                       public base::RefCountedThreadSafe<GpuChannelHost>,
87                       public base::SupportsWeakPtr<GpuChannelHost> {
88 public:
89  enum State {
90    // Not yet connected.
91    kUnconnected,
92    // Ready to use.
93    kConnected,
94    // An error caused the host to become disconnected. Recreate channel to
95    // reestablish connection.
96    kLost
97  };
98
99  // Called on the render thread
100  GpuChannelHost(GpuChannelHostFactory* factory,
101                 int gpu_host_id,
102                 int client_id);
103
104  // Connect to GPU process channel.
105  void Connect(const IPC::ChannelHandle& channel_handle);
106
107  State state() const { return state_; }
108
109  // Change state to kLost.
110  void SetStateLost();
111
112  // The GPU stats reported by the GPU process.
113  void set_gpu_info(const GPUInfo& gpu_info);
114  const GPUInfo& gpu_info() const;
115
116  void OnMessageReceived(const IPC::Message& message);
117  void OnChannelError();
118
119  // IPC::Sender implementation:
120  virtual bool Send(IPC::Message* msg) OVERRIDE;
121
122  // Create and connect to a command buffer in the GPU process.
123  CommandBufferProxyImpl* CreateViewCommandBuffer(
124      int32 surface_id,
125      CommandBufferProxyImpl* share_group,
126      const std::string& allowed_extensions,
127      const std::vector<int32>& attribs,
128      const GURL& active_url,
129      gfx::GpuPreference gpu_preference);
130
131  // Create and connect to a command buffer in the GPU process.
132  CommandBufferProxyImpl* CreateOffscreenCommandBuffer(
133      const gfx::Size& size,
134      CommandBufferProxyImpl* share_group,
135      const std::string& allowed_extensions,
136      const std::vector<int32>& attribs,
137      const GURL& active_url,
138      gfx::GpuPreference gpu_preference);
139
140  // Creates a video decoder in the GPU process.
141  scoped_ptr<media::VideoDecodeAccelerator> CreateVideoDecoder(
142      int command_buffer_route_id,
143      media::VideoCodecProfile profile,
144      media::VideoDecodeAccelerator::Client* client);
145
146  // Destroy a command buffer created by this channel.
147  void DestroyCommandBuffer(CommandBufferProxyImpl* command_buffer);
148
149  // Collect rendering stats from GPU process.
150  bool CollectRenderingStatsForSurface(
151      int surface_id, GpuRenderingStats* stats);
152
153  // Add a route for the current message loop.
154  void AddRoute(int route_id, base::WeakPtr<IPC::Listener> listener);
155  void RemoveRoute(int route_id);
156
157  GpuChannelHostFactory* factory() const { return factory_; }
158  int gpu_host_id() const { return gpu_host_id_; }
159
160  int client_id() const { return client_id_; }
161
162  // Returns a handle to the shared memory that can be sent via IPC to the
163  // GPU process. The caller is responsible for ensuring it is closed. Returns
164  // an invalid handle on failure.
165  base::SharedMemoryHandle ShareToGpuProcess(
166      base::SharedMemoryHandle source_handle);
167
168  // Generates n unique mailbox names that can be used with
169  // GL_texture_mailbox_CHROMIUM. Unlike genMailboxCHROMIUM, this IPC is
170  // handled only on the GPU process' IO thread, and so is not effectively
171  // a finish.
172  bool GenerateMailboxNames(unsigned num, std::vector<gpu::Mailbox>* names);
173
174  // Reserve one unused transfer buffer ID.
175  int32 ReserveTransferBufferId();
176
177 private:
178  friend class base::RefCountedThreadSafe<GpuChannelHost>;
179  virtual ~GpuChannelHost();
180
181  // Message handlers.
182  void OnGenerateMailboxNamesReply(const std::vector<gpu::Mailbox>& names);
183
184  // A filter used internally to route incoming messages from the IO thread
185  // to the correct message loop.
186  class MessageFilter : public IPC::ChannelProxy::MessageFilter {
187   public:
188    MessageFilter(base::WeakPtr<GpuChannelHost> parent,
189                  GpuChannelHostFactory* factory);
190
191    void AddRoute(int route_id,
192                  base::WeakPtr<IPC::Listener> listener,
193                  scoped_refptr<base::MessageLoopProxy> loop);
194    void RemoveRoute(int route_id);
195
196    // IPC::ChannelProxy::MessageFilter implementation:
197    virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE;
198    virtual void OnChannelError() OVERRIDE;
199
200   private:
201    virtual ~MessageFilter();
202
203    // Note: this reference can only be used to post tasks back to the
204    // GpuChannelHost, it is illegal to dereference on the IO thread where the
205    // MessageFilter lives.
206    base::WeakPtr<GpuChannelHost> parent_;
207
208    scoped_refptr<base::MessageLoopProxy> main_thread_loop_;
209
210    typedef base::hash_map<int, GpuListenerInfo> ListenerMap;
211    ListenerMap listeners_;
212  };
213
214  GpuChannelHostFactory* factory_;
215  int client_id_;
216  int gpu_host_id_;
217
218  State state_;
219
220  GPUInfo gpu_info_;
221
222  scoped_ptr<IPC::SyncChannel> channel_;
223  scoped_refptr<MessageFilter> channel_filter_;
224
225  // Used to look up a proxy from its routing id.
226  typedef base::hash_map<int, CommandBufferProxyImpl*> ProxyMap;
227  ProxyMap proxies_;
228
229  // A lock to guard against concurrent access to members like the proxies map
230  // for calls from contexts that may live on the compositor or main thread.
231  mutable base::Lock context_lock_;
232
233  // A filter for sending messages from thread other than the main thread.
234  scoped_refptr<IPC::SyncMessageFilter> sync_filter_;
235
236  // A pool of valid mailbox names.
237  std::vector<gpu::Mailbox> mailbox_name_pool_;
238
239  // Transfer buffer IDs are allocated in sequence.
240  base::AtomicSequenceNumber next_transfer_buffer_id_;
241
242  DISALLOW_COPY_AND_ASSIGN(GpuChannelHost);
243};
244
245}  // namespace content
246
247#endif  // CONTENT_COMMON_GPU_CLIENT_GPU_CHANNEL_HOST_H_
248