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_GPU_CHANNEL_H_
6#define CONTENT_COMMON_GPU_GPU_CHANNEL_H_
7
8#include <deque>
9#include <string>
10
11#include "base/id_map.h"
12#include "base/memory/ref_counted.h"
13#include "base/memory/scoped_ptr.h"
14#include "base/memory/scoped_vector.h"
15#include "base/memory/weak_ptr.h"
16#include "base/process/process.h"
17#include "build/build_config.h"
18#include "content/common/gpu/gpu_command_buffer_stub.h"
19#include "content/common/gpu/gpu_memory_manager.h"
20#include "content/common/gpu/gpu_result_codes.h"
21#include "content/common/message_router.h"
22#include "ipc/ipc_sync_channel.h"
23#include "ui/gfx/native_widget_types.h"
24#include "ui/gfx/size.h"
25#include "ui/gl/gl_share_group.h"
26#include "ui/gl/gpu_preference.h"
27
28struct GPUCreateCommandBufferConfig;
29
30namespace base {
31class MessageLoopProxy;
32class WaitableEvent;
33}
34
35namespace gpu {
36class PreemptionFlag;
37}
38
39namespace IPC {
40class MessageFilter;
41}
42
43namespace content {
44class DevToolsGpuAgent;
45class GpuChannelManager;
46class GpuChannelMessageFilter;
47class GpuWatchdog;
48
49// Encapsulates an IPC channel between the GPU process and one renderer
50// process. On the renderer side there's a corresponding GpuChannelHost.
51class GpuChannel : public IPC::Listener, public IPC::Sender {
52 public:
53  // Takes ownership of the renderer process handle.
54  GpuChannel(GpuChannelManager* gpu_channel_manager,
55             GpuWatchdog* watchdog,
56             gfx::GLShareGroup* share_group,
57             gpu::gles2::MailboxManager* mailbox_manager,
58             int client_id,
59             bool software,
60             bool allow_future_sync_points);
61  virtual ~GpuChannel();
62
63  void Init(base::MessageLoopProxy* io_message_loop,
64            base::WaitableEvent* shutdown_event);
65
66  // Get the GpuChannelManager that owns this channel.
67  GpuChannelManager* gpu_channel_manager() const {
68    return gpu_channel_manager_;
69  }
70
71  // Returns the name of the associated IPC channel.
72  std::string GetChannelName();
73
74#if defined(OS_POSIX)
75  int TakeRendererFileDescriptor();
76#endif  // defined(OS_POSIX)
77
78  base::ProcessId renderer_pid() const { return channel_->GetPeerPID(); }
79
80  int client_id() const { return client_id_; }
81
82  scoped_refptr<base::MessageLoopProxy> io_message_loop() const {
83    return io_message_loop_;
84  }
85
86  // IPC::Listener implementation:
87  virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE;
88  virtual void OnChannelError() OVERRIDE;
89
90  // IPC::Sender implementation:
91  virtual bool Send(IPC::Message* msg) OVERRIDE;
92
93  // Requeue the message that is currently being processed to the beginning of
94  // the queue. Used when the processing of a message gets aborted because of
95  // unscheduling conditions.
96  void RequeueMessage();
97
98  // This is called when a command buffer transitions from the unscheduled
99  // state to the scheduled state, which potentially means the channel
100  // transitions from the unscheduled to the scheduled state. When this occurs
101  // deferred IPC messaged are handled.
102  void OnScheduled();
103
104  // This is called when a command buffer transitions between scheduled and
105  // descheduled states. When any stub is descheduled, we stop preempting
106  // other channels.
107  void StubSchedulingChanged(bool scheduled);
108
109  CreateCommandBufferResult CreateViewCommandBuffer(
110      const gfx::GLSurfaceHandle& window,
111      int32 surface_id,
112      const GPUCreateCommandBufferConfig& init_params,
113      int32 route_id);
114
115  gfx::GLShareGroup* share_group() const { return share_group_.get(); }
116
117  GpuCommandBufferStub* LookupCommandBuffer(int32 route_id);
118
119  void LoseAllContexts();
120  void MarkAllContextsLost();
121
122  // Called to add a listener for a particular message routing ID.
123  // Returns true if succeeded.
124  bool AddRoute(int32 route_id, IPC::Listener* listener);
125
126  // Called to remove a listener for a particular message routing ID.
127  void RemoveRoute(int32 route_id);
128
129  gpu::PreemptionFlag* GetPreemptionFlag();
130
131  bool handle_messages_scheduled() const { return handle_messages_scheduled_; }
132  uint64 messages_processed() const { return messages_processed_; }
133
134  // If |preemption_flag->IsSet()|, any stub on this channel
135  // should stop issuing GL commands. Setting this to NULL stops deferral.
136  void SetPreemptByFlag(
137      scoped_refptr<gpu::PreemptionFlag> preemption_flag);
138
139  void CacheShader(const std::string& key, const std::string& shader);
140
141  void AddFilter(IPC::MessageFilter* filter);
142  void RemoveFilter(IPC::MessageFilter* filter);
143
144  uint64 GetMemoryUsage();
145
146  bool allow_future_sync_points() const { return allow_future_sync_points_; }
147
148 private:
149  friend class GpuChannelMessageFilter;
150
151  void OnDestroy();
152
153  bool OnControlMessageReceived(const IPC::Message& msg);
154
155  void HandleMessage();
156
157  // Message handlers.
158  void OnCreateOffscreenCommandBuffer(
159      const gfx::Size& size,
160      const GPUCreateCommandBufferConfig& init_params,
161      int32 route_id,
162      bool* succeeded);
163  void OnDestroyCommandBuffer(int32 route_id);
164  void OnDevToolsStartEventsRecording(int32 route_id, bool* succeeded);
165  void OnDevToolsStopEventsRecording();
166
167  // Decrement the count of unhandled IPC messages and defer preemption.
168  void MessageProcessed();
169
170  // Try to match the messages pattern for GL SwapBuffers operation in the
171  // deferred message queue starting from the current processing message.
172  // Return the number of messages that matches the given pattern, e.g.
173  // AsyncFlush -> Echo sequence.
174  size_t MatchSwapBufferMessagesPattern(IPC::Message* current_message);
175
176  // The lifetime of objects of this class is managed by a GpuChannelManager.
177  // The GpuChannelManager destroy all the GpuChannels that they own when they
178  // are destroyed. So a raw pointer is safe.
179  GpuChannelManager* gpu_channel_manager_;
180
181  scoped_ptr<IPC::SyncChannel> channel_;
182
183  uint64 messages_processed_;
184
185  // Whether the processing of IPCs on this channel is stalled and we should
186  // preempt other GpuChannels.
187  scoped_refptr<gpu::PreemptionFlag> preempting_flag_;
188
189  // If non-NULL, all stubs on this channel should stop processing GL
190  // commands (via their GpuScheduler) when preempted_flag_->IsSet()
191  scoped_refptr<gpu::PreemptionFlag> preempted_flag_;
192
193  std::deque<IPC::Message*> deferred_messages_;
194
195  // The id of the client who is on the other side of the channel.
196  int client_id_;
197
198  // Uniquely identifies the channel within this GPU process.
199  std::string channel_id_;
200
201  // Used to implement message routing functionality to CommandBuffer objects
202  MessageRouter router_;
203
204  // The share group that all contexts associated with a particular renderer
205  // process use.
206  scoped_refptr<gfx::GLShareGroup> share_group_;
207
208  scoped_refptr<gpu::gles2::MailboxManager> mailbox_manager_;
209
210  typedef IDMap<GpuCommandBufferStub, IDMapOwnPointer> StubMap;
211  StubMap stubs_;
212
213  bool log_messages_;  // True if we should log sent and received messages.
214  gpu::gles2::DisallowedFeatures disallowed_features_;
215  GpuWatchdog* watchdog_;
216  bool software_;
217  bool handle_messages_scheduled_;
218  IPC::Message* currently_processing_message_;
219
220  scoped_refptr<GpuChannelMessageFilter> filter_;
221  scoped_refptr<base::MessageLoopProxy> io_message_loop_;
222  scoped_ptr<DevToolsGpuAgent> devtools_gpu_agent_;
223
224  size_t num_stubs_descheduled_;
225
226  bool allow_future_sync_points_;
227
228  // Member variables should appear before the WeakPtrFactory, to ensure
229  // that any WeakPtrs to Controller are invalidated before its members
230  // variable's destructors are executed, rendering them invalid.
231  base::WeakPtrFactory<GpuChannel> weak_factory_;
232
233  DISALLOW_COPY_AND_ASSIGN(GpuChannel);
234};
235
236}  // namespace content
237
238#endif  // CONTENT_COMMON_GPU_GPU_CHANNEL_H_
239