1// Copyright 2013 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 GPU_COMMAND_BUFFER_SERVICE_IN_PROCESS_COMMAND_BUFFER_H_
6#define GPU_COMMAND_BUFFER_SERVICE_IN_PROCESS_COMMAND_BUFFER_H_
7
8#include <map>
9#include <vector>
10
11#include "base/callback.h"
12#include "base/compiler_specific.h"
13#include "base/containers/scoped_ptr_hash_map.h"
14#include "base/memory/ref_counted.h"
15#include "base/memory/scoped_ptr.h"
16#include "base/memory/weak_ptr.h"
17#include "base/synchronization/lock.h"
18#include "base/synchronization/waitable_event.h"
19#include "gpu/command_buffer/client/gpu_control.h"
20#include "gpu/command_buffer/common/command_buffer.h"
21#include "gpu/gpu_export.h"
22#include "ui/gfx/gpu_memory_buffer.h"
23#include "ui/gfx/native_widget_types.h"
24#include "ui/gl/gl_surface.h"
25#include "ui/gl/gpu_preference.h"
26
27namespace base {
28class SequenceChecker;
29}
30
31namespace gfx {
32class GLContext;
33class GLShareGroup;
34class GLSurface;
35class Size;
36}
37
38#if defined(OS_ANDROID)
39namespace gfx {
40class SurfaceTexture;
41}
42namespace gpu {
43class StreamTextureManagerInProcess;
44}
45#endif
46
47namespace gpu {
48
49namespace gles2 {
50class GLES2Decoder;
51class MailboxManager;
52class ShaderTranslatorCache;
53}
54
55class CommandBufferServiceBase;
56class GpuScheduler;
57class TransferBufferManagerInterface;
58
59// TODO(reveman): Remove this interface when InProcessCommandBuffer doesn't need
60// a custom factory interface and android_webview implementation of GPU memory
61// buffers can use the same mechanism for buffer allocation as what's used for
62// out of process GPU service.
63class GPU_EXPORT InProcessGpuMemoryBufferFactory {
64 public:
65  virtual scoped_ptr<gfx::GpuMemoryBuffer> AllocateGpuMemoryBuffer(
66      size_t width,
67      size_t height,
68      unsigned internalformat,
69      unsigned usage) = 0;
70  virtual scoped_refptr<gfx::GLImage> CreateImageForGpuMemoryBuffer(
71      const gfx::GpuMemoryBufferHandle& handle,
72      const gfx::Size& size,
73      unsigned internalformat) = 0;
74
75 protected:
76  virtual ~InProcessGpuMemoryBufferFactory() {}
77};
78
79// This class provides a thread-safe interface to the global GPU service (for
80// example GPU thread) when being run in single process mode.
81// However, the behavior for accessing one context (i.e. one instance of this
82// class) from different client threads is undefined.
83class GPU_EXPORT InProcessCommandBuffer : public CommandBuffer,
84                                          public GpuControl {
85 public:
86  class Service;
87  explicit InProcessCommandBuffer(const scoped_refptr<Service>& service);
88  virtual ~InProcessCommandBuffer();
89
90  static void SetGpuMemoryBufferFactory(
91      InProcessGpuMemoryBufferFactory* factory);
92
93  // If |surface| is not NULL, use it directly; in this case, the command
94  // buffer gpu thread must be the same as the client thread. Otherwise create
95  // a new GLSurface.
96  bool Initialize(scoped_refptr<gfx::GLSurface> surface,
97                  bool is_offscreen,
98                  gfx::AcceleratedWidget window,
99                  const gfx::Size& size,
100                  const std::vector<int32>& attribs,
101                  gfx::GpuPreference gpu_preference,
102                  const base::Closure& context_lost_callback,
103                  InProcessCommandBuffer* share_group);
104  void Destroy();
105
106  // CommandBuffer implementation:
107  virtual bool Initialize() OVERRIDE;
108  virtual State GetLastState() OVERRIDE;
109  virtual int32 GetLastToken() OVERRIDE;
110  virtual void Flush(int32 put_offset) OVERRIDE;
111  virtual void WaitForTokenInRange(int32 start, int32 end) OVERRIDE;
112  virtual void WaitForGetOffsetInRange(int32 start, int32 end) OVERRIDE;
113  virtual void SetGetBuffer(int32 shm_id) OVERRIDE;
114  virtual scoped_refptr<gpu::Buffer> CreateTransferBuffer(size_t size,
115                                                          int32* id) OVERRIDE;
116  virtual void DestroyTransferBuffer(int32 id) OVERRIDE;
117  virtual gpu::error::Error GetLastError() OVERRIDE;
118
119  // GpuControl implementation:
120  virtual gpu::Capabilities GetCapabilities() OVERRIDE;
121  virtual gfx::GpuMemoryBuffer* CreateGpuMemoryBuffer(size_t width,
122                                                      size_t height,
123                                                      unsigned internalformat,
124                                                      unsigned usage,
125                                                      int32* id) OVERRIDE;
126  virtual void DestroyGpuMemoryBuffer(int32 id) OVERRIDE;
127  virtual uint32 InsertSyncPoint() OVERRIDE;
128  virtual uint32 InsertFutureSyncPoint() OVERRIDE;
129  virtual void RetireSyncPoint(uint32 sync_point) OVERRIDE;
130  virtual void SignalSyncPoint(uint32 sync_point,
131                               const base::Closure& callback) OVERRIDE;
132  virtual void SignalQuery(uint32 query_id,
133                           const base::Closure& callback) OVERRIDE;
134  virtual void SetSurfaceVisible(bool visible) OVERRIDE;
135  virtual void Echo(const base::Closure& callback) OVERRIDE;
136  virtual uint32 CreateStreamTexture(uint32 texture_id) OVERRIDE;
137
138  // The serializer interface to the GPU service (i.e. thread).
139  class Service {
140   public:
141    Service();
142    virtual ~Service();
143
144    virtual void AddRef() const = 0;
145    virtual void Release() const = 0;
146
147    // Queues a task to run as soon as possible.
148    virtual void ScheduleTask(const base::Closure& task) = 0;
149
150    // Schedules |callback| to run at an appropriate time for performing idle
151    // work.
152    virtual void ScheduleIdleWork(const base::Closure& task) = 0;
153
154    virtual bool UseVirtualizedGLContexts() = 0;
155    virtual scoped_refptr<gles2::ShaderTranslatorCache>
156        shader_translator_cache() = 0;
157    scoped_refptr<gles2::MailboxManager> mailbox_manager();
158
159   private:
160    scoped_refptr<gles2::MailboxManager> mailbox_manager_;
161  };
162
163#if defined(OS_ANDROID)
164  scoped_refptr<gfx::SurfaceTexture> GetSurfaceTexture(
165      uint32 stream_id);
166#endif
167
168 private:
169  struct InitializeOnGpuThreadParams {
170    bool is_offscreen;
171    gfx::AcceleratedWidget window;
172    const gfx::Size& size;
173    const std::vector<int32>& attribs;
174    gfx::GpuPreference gpu_preference;
175    gpu::Capabilities* capabilities;  // Ouptut.
176    InProcessCommandBuffer* context_group;
177
178    InitializeOnGpuThreadParams(bool is_offscreen,
179                                gfx::AcceleratedWidget window,
180                                const gfx::Size& size,
181                                const std::vector<int32>& attribs,
182                                gfx::GpuPreference gpu_preference,
183                                gpu::Capabilities* capabilities,
184                                InProcessCommandBuffer* share_group)
185        : is_offscreen(is_offscreen),
186          window(window),
187          size(size),
188          attribs(attribs),
189          gpu_preference(gpu_preference),
190          capabilities(capabilities),
191          context_group(share_group) {}
192  };
193
194  bool InitializeOnGpuThread(const InitializeOnGpuThreadParams& params);
195  bool DestroyOnGpuThread();
196  void FlushOnGpuThread(int32 put_offset);
197  void ScheduleIdleWorkOnGpuThread();
198  uint32 CreateStreamTextureOnGpuThread(uint32 client_texture_id);
199  bool MakeCurrent();
200  base::Closure WrapCallback(const base::Closure& callback);
201  State GetStateFast();
202  void QueueTask(const base::Closure& task) { service_->ScheduleTask(task); }
203  void CheckSequencedThread();
204  void RetireSyncPointOnGpuThread(uint32 sync_point);
205  void SignalSyncPointOnGpuThread(uint32 sync_point,
206                                  const base::Closure& callback);
207  bool WaitSyncPointOnGpuThread(uint32 sync_point);
208  void SignalQueryOnGpuThread(unsigned query_id, const base::Closure& callback);
209  void DestroyTransferBufferOnGpuThread(int32 id);
210  void RegisterGpuMemoryBufferOnGpuThread(
211      int32 id,
212      const gfx::GpuMemoryBufferHandle& handle,
213      size_t width,
214      size_t height,
215      unsigned internalformat);
216  void UnregisterGpuMemoryBufferOnGpuThread(int32 id);
217
218  // Callbacks:
219  void OnContextLost();
220  void OnResizeView(gfx::Size size, float scale_factor);
221  bool GetBufferChanged(int32 transfer_buffer_id);
222  void PumpCommands();
223  void PerformIdleWork();
224
225  static scoped_refptr<Service> GetDefaultService();
226
227  // Members accessed on the gpu thread (possibly with the exception of
228  // creation):
229  bool context_lost_;
230  scoped_ptr<TransferBufferManagerInterface> transfer_buffer_manager_;
231  scoped_ptr<GpuScheduler> gpu_scheduler_;
232  scoped_ptr<gles2::GLES2Decoder> decoder_;
233  scoped_refptr<gfx::GLContext> context_;
234  scoped_refptr<gfx::GLSurface> surface_;
235  base::Closure context_lost_callback_;
236  bool idle_work_pending_;  // Used to throttle PerformIdleWork.
237
238  // Members accessed on the client thread:
239  State last_state_;
240  int32 last_put_offset_;
241  gpu::Capabilities capabilities_;
242  typedef base::ScopedPtrHashMap<int32, gfx::GpuMemoryBuffer>
243      GpuMemoryBufferMap;
244  GpuMemoryBufferMap gpu_memory_buffers_;
245
246  // Accessed on both threads:
247  scoped_ptr<CommandBufferServiceBase> command_buffer_;
248  base::Lock command_buffer_lock_;
249  base::WaitableEvent flush_event_;
250  scoped_refptr<Service> service_;
251  State state_after_last_flush_;
252  base::Lock state_after_last_flush_lock_;
253  scoped_refptr<gfx::GLShareGroup> gl_share_group_;
254
255#if defined(OS_ANDROID)
256  scoped_ptr<StreamTextureManagerInProcess> stream_texture_manager_;
257#endif
258
259  // Only used with explicit scheduling and the gpu thread is the same as
260  // the client thread.
261  scoped_ptr<base::SequenceChecker> sequence_checker_;
262
263  base::WeakPtr<InProcessCommandBuffer> gpu_thread_weak_ptr_;
264  base::WeakPtrFactory<InProcessCommandBuffer> gpu_thread_weak_ptr_factory_;
265
266  DISALLOW_COPY_AND_ASSIGN(InProcessCommandBuffer);
267};
268
269}  // namespace gpu
270
271#endif  // GPU_COMMAND_BUFFER_SERVICE_IN_PROCESS_COMMAND_BUFFER_H_
272