• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_WEBGRAPHICSCONTEXT3D_COMMAND_BUFFER_IMPL_H_
6 #define CONTENT_COMMON_GPU_CLIENT_WEBGRAPHICSCONTEXT3D_COMMAND_BUFFER_IMPL_H_
7 
8 #include <string>
9 #include <vector>
10 
11 #include "base/callback.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/memory/weak_ptr.h"
14 #include "base/synchronization/lock.h"
15 #include "content/common/content_export.h"
16 #include "content/common/gpu/client/command_buffer_proxy_impl.h"
17 #include "third_party/WebKit/public/platform/WebGraphicsContext3D.h"
18 #include "third_party/WebKit/public/platform/WebString.h"
19 #include "ui/gfx/native_widget_types.h"
20 #include "ui/gl/gpu_preference.h"
21 #include "url/gurl.h"
22 #include "webkit/common/gpu/webgraphicscontext3d_impl.h"
23 
24 namespace gpu {
25 
26 class ContextSupport;
27 class TransferBuffer;
28 
29 namespace gles2 {
30 class GLES2CmdHelper;
31 class GLES2Implementation;
32 class GLES2Interface;
33 }
34 }
35 
36 namespace content {
37 class GpuChannelHost;
38 
39 const size_t kDefaultCommandBufferSize = 1024 * 1024;
40 const size_t kDefaultStartTransferBufferSize = 1 * 1024 * 1024;
41 const size_t kDefaultMinTransferBufferSize = 1 * 256 * 1024;
42 const size_t kDefaultMaxTransferBufferSize = 16 * 1024 * 1024;
43 
44 class WebGraphicsContext3DCommandBufferImpl
45     : public webkit::gpu::WebGraphicsContext3DImpl {
46  public:
47   enum MappedMemoryReclaimLimit {
48     kNoLimit = 0,
49   };
50 
51   struct CONTENT_EXPORT SharedMemoryLimits {
52     SharedMemoryLimits();
53 
54     size_t command_buffer_size;
55     size_t start_transfer_buffer_size;
56     size_t min_transfer_buffer_size;
57     size_t max_transfer_buffer_size;
58     size_t mapped_memory_reclaim_limit;
59   };
60 
61   class ShareGroup : public base::RefCountedThreadSafe<ShareGroup> {
62    public:
63     ShareGroup();
64 
GetAnyContextLocked()65     WebGraphicsContext3DCommandBufferImpl* GetAnyContextLocked() {
66       // In order to ensure that the context returned is not removed while
67       // in use, the share group's lock should be aquired before calling this
68       // function.
69       lock_.AssertAcquired();
70       if (contexts_.empty())
71         return NULL;
72       return contexts_.front();
73     }
74 
AddContextLocked(WebGraphicsContext3DCommandBufferImpl * context)75     void AddContextLocked(WebGraphicsContext3DCommandBufferImpl* context) {
76       lock_.AssertAcquired();
77       contexts_.push_back(context);
78     }
79 
RemoveContext(WebGraphicsContext3DCommandBufferImpl * context)80     void RemoveContext(WebGraphicsContext3DCommandBufferImpl* context) {
81       base::AutoLock auto_lock(lock_);
82       contexts_.erase(std::remove(contexts_.begin(), contexts_.end(), context),
83           contexts_.end());
84     }
85 
RemoveAllContexts()86     void RemoveAllContexts() {
87       base::AutoLock auto_lock(lock_);
88       contexts_.clear();
89     }
90 
lock()91     base::Lock& lock() {
92       return lock_;
93     }
94 
95    private:
96     friend class base::RefCountedThreadSafe<ShareGroup>;
97     virtual ~ShareGroup();
98 
99     std::vector<WebGraphicsContext3DCommandBufferImpl*> contexts_;
100     base::Lock lock_;
101 
102     DISALLOW_COPY_AND_ASSIGN(ShareGroup);
103   };
104 
105   WebGraphicsContext3DCommandBufferImpl(
106       int surface_id,
107       const GURL& active_url,
108       GpuChannelHost* host,
109       const Attributes& attributes,
110       bool lose_context_when_out_of_memory,
111       const SharedMemoryLimits& limits,
112       WebGraphicsContext3DCommandBufferImpl* share_context);
113 
114   virtual ~WebGraphicsContext3DCommandBufferImpl();
115 
GetCommandBufferProxy()116   CommandBufferProxyImpl* GetCommandBufferProxy() {
117     return command_buffer_.get();
118   }
119 
120   CONTENT_EXPORT gpu::ContextSupport* GetContextSupport();
121 
GetImplementation()122   gpu::gles2::GLES2Implementation* GetImplementation() {
123     return real_gl_.get();
124   }
125 
126   // Return true if GPU process reported context lost or there was a
127   // problem communicating with the GPU process.
128   bool IsCommandBufferContextLost();
129 
130   // Create & initialize a WebGraphicsContext3DCommandBufferImpl.  Return NULL
131   // on any failure.
132   static CONTENT_EXPORT WebGraphicsContext3DCommandBufferImpl*
133       CreateOffscreenContext(
134           GpuChannelHost* host,
135           const WebGraphicsContext3D::Attributes& attributes,
136           bool lose_context_when_out_of_memory,
137           const GURL& active_url,
138           const SharedMemoryLimits& limits,
139           WebGraphicsContext3DCommandBufferImpl* share_context);
140 
GetMappedMemoryLimit()141   size_t GetMappedMemoryLimit() {
142     return mem_limits_.mapped_memory_reclaim_limit;
143   }
144 
145   //----------------------------------------------------------------------
146   // WebGraphicsContext3D methods
147 
148   // Must be called after initialize() and before any of the following methods.
149   // Permanently binds to the first calling thread. Returns false if the
150   // graphics context fails to create. Do not call from more than one thread.
151   virtual bool makeContextCurrent();
152 
153   virtual bool isContextLost();
154 
155   virtual WGC3Denum getGraphicsResetStatusARB();
156 
157  private:
158   // These are the same error codes as used by EGL.
159   enum Error {
160     SUCCESS               = 0x3000,
161     BAD_ATTRIBUTE         = 0x3004,
162     CONTEXT_LOST          = 0x300E
163   };
164   // WebGraphicsContext3DCommandBufferImpl configuration attributes. Those in
165   // the 16-bit range are the same as used by EGL. Those outside the 16-bit
166   // range are unique to Chromium. Attributes are matched using a closest fit
167   // algorithm.
168   // Changes to this enum should also be copied to
169   // gpu/command_buffer/common/gles2_cmd_utils.cc and to
170   // gpu/command_buffer/client/gl_in_process_context.cc
171   enum Attribute {
172     ALPHA_SIZE = 0x3021,
173     BLUE_SIZE = 0x3022,
174     GREEN_SIZE = 0x3023,
175     RED_SIZE = 0x3024,
176     DEPTH_SIZE = 0x3025,
177     STENCIL_SIZE = 0x3026,
178     SAMPLES = 0x3031,
179     SAMPLE_BUFFERS = 0x3032,
180     HEIGHT = 0x3056,
181     WIDTH = 0x3057,
182     NONE = 0x3038,  // Attrib list = terminator
183     SHARE_RESOURCES = 0x10000,
184     BIND_GENERATES_RESOURCES = 0x10001,
185     FAIL_IF_MAJOR_PERF_CAVEAT = 0x10002,
186     LOSE_CONTEXT_WHEN_OUT_OF_MEMORY = 0x10003,
187   };
188 
189   // Initialize the underlying GL context. May be called multiple times; second
190   // and subsequent calls are ignored. Must be called from the thread that is
191   // going to use this object to issue GL commands (which might not be the main
192   // thread).
193   bool MaybeInitializeGL();
194 
195   bool InitializeCommandBuffer(bool onscreen,
196       WebGraphicsContext3DCommandBufferImpl* share_context);
197 
198   void Destroy();
199 
200   // Create a CommandBufferProxy that renders directly to a view. The view and
201   // the associated window must not be destroyed until the returned
202   // CommandBufferProxy has been destroyed, otherwise the GPU process might
203   // attempt to render to an invalid window handle.
204   //
205   // NOTE: on Mac OS X, this entry point is only used to set up the
206   // accelerated compositor's output. On this platform, we actually pass
207   // a gfx::PluginWindowHandle in place of the gfx::NativeViewId,
208   // because the facility to allocate a fake PluginWindowHandle is
209   // already in place. We could add more entry points and messages to
210   // allocate both fake PluginWindowHandles and NativeViewIds and map
211   // from fake NativeViewIds to PluginWindowHandles, but this seems like
212   // unnecessary complexity at the moment.
213   bool CreateContext(bool onscreen);
214 
215   virtual void OnGpuChannelLost();
216 
217   bool lose_context_when_out_of_memory_;
218   blink::WebGraphicsContext3D::Attributes attributes_;
219 
220   bool visible_;
221 
222   // State needed by MaybeInitializeGL.
223   scoped_refptr<GpuChannelHost> host_;
224   int32 surface_id_;
225   GURL active_url_;
226 
227   gfx::GpuPreference gpu_preference_;
228 
229   base::WeakPtrFactory<WebGraphicsContext3DCommandBufferImpl> weak_ptr_factory_;
230 
231   scoped_ptr<CommandBufferProxyImpl> command_buffer_;
232   scoped_ptr<gpu::gles2::GLES2CmdHelper> gles2_helper_;
233   scoped_ptr<gpu::TransferBuffer> transfer_buffer_;
234   scoped_ptr<gpu::gles2::GLES2Implementation> real_gl_;
235   scoped_ptr<gpu::gles2::GLES2Interface> trace_gl_;
236   Error last_error_;
237   SharedMemoryLimits mem_limits_;
238   scoped_refptr<ShareGroup> share_group_;
239 };
240 
241 }  // namespace content
242 
243 #endif  // CONTENT_COMMON_GPU_CLIENT_WEBGRAPHICSCONTEXT3D_COMMAND_BUFFER_IMPL_H_
244