OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "gpu/command_buffer/client/gl_in_process_context.h" | 5 #include "gpu/command_buffer/client/gl_in_process_context.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 #include <utility> | 8 #include <utility> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 19 matching lines...) Expand all Loading... |
30 #include "ui/gl/gl_image.h" | 30 #include "ui/gl/gl_image.h" |
31 | 31 |
32 #if defined(OS_ANDROID) | 32 #if defined(OS_ANDROID) |
33 #include "ui/gl/android/surface_texture.h" | 33 #include "ui/gl/android/surface_texture.h" |
34 #endif | 34 #endif |
35 | 35 |
36 namespace gpu { | 36 namespace gpu { |
37 | 37 |
38 namespace { | 38 namespace { |
39 | 39 |
40 const int32 kCommandBufferSize = 1024 * 1024; | 40 const int32 kDefaultCommandBufferSize = 1024 * 1024; |
41 // TODO(kbr): make the transfer buffer size configurable via context | 41 const unsigned int kDefaultStartTransferBufferSize = 4 * 1024 * 1024; |
42 // creation attributes. | 42 const unsigned int kDefaultMinTransferBufferSize = 1 * 256 * 1024; |
43 const size_t kStartTransferBufferSize = 4 * 1024 * 1024; | 43 const unsigned int kDefaultMaxTransferBufferSize = 16 * 1024 * 1024; |
44 const size_t kMinTransferBufferSize = 1 * 256 * 1024; | |
45 const size_t kMaxTransferBufferSize = 16 * 1024 * 1024; | |
46 | 44 |
47 class GLInProcessContextImpl | 45 class GLInProcessContextImpl |
48 : public GLInProcessContext, | 46 : public GLInProcessContext, |
49 public base::SupportsWeakPtr<GLInProcessContextImpl> { | 47 public base::SupportsWeakPtr<GLInProcessContextImpl> { |
50 public: | 48 public: |
51 explicit GLInProcessContextImpl(); | 49 explicit GLInProcessContextImpl( |
| 50 const GLInProcessContextSharedMemoryLimits& mem_limits); |
52 virtual ~GLInProcessContextImpl(); | 51 virtual ~GLInProcessContextImpl(); |
53 | 52 |
54 bool Initialize( | 53 bool Initialize( |
55 scoped_refptr<gfx::GLSurface> surface, | 54 scoped_refptr<gfx::GLSurface> surface, |
56 bool is_offscreen, | 55 bool is_offscreen, |
57 bool use_global_share_group, | 56 bool use_global_share_group, |
58 GLInProcessContext* share_context, | 57 GLInProcessContext* share_context, |
59 gfx::AcceleratedWidget window, | 58 gfx::AcceleratedWidget window, |
60 const gfx::Size& size, | 59 const gfx::Size& size, |
61 const gpu::gles2::ContextCreationAttribHelper& attribs, | 60 const gpu::gles2::ContextCreationAttribHelper& attribs, |
62 gfx::GpuPreference gpu_preference, | 61 gfx::GpuPreference gpu_preference, |
63 const scoped_refptr<InProcessCommandBuffer::Service>& service); | 62 const scoped_refptr<InProcessCommandBuffer::Service>& service); |
64 | 63 |
65 // GLInProcessContext implementation: | 64 // GLInProcessContext implementation: |
66 virtual void SetContextLostCallback(const base::Closure& callback) OVERRIDE; | 65 virtual void SetContextLostCallback(const base::Closure& callback) OVERRIDE; |
67 virtual gles2::GLES2Implementation* GetImplementation() OVERRIDE; | 66 virtual gles2::GLES2Implementation* GetImplementation() OVERRIDE; |
| 67 virtual size_t GetMappedMemoryLimit() OVERRIDE; |
68 | 68 |
69 #if defined(OS_ANDROID) | 69 #if defined(OS_ANDROID) |
70 virtual scoped_refptr<gfx::SurfaceTexture> GetSurfaceTexture( | 70 virtual scoped_refptr<gfx::SurfaceTexture> GetSurfaceTexture( |
71 uint32 stream_id) OVERRIDE; | 71 uint32 stream_id) OVERRIDE; |
72 #endif | 72 #endif |
73 | 73 |
74 private: | 74 private: |
75 void Destroy(); | 75 void Destroy(); |
76 void OnContextLost(); | 76 void OnContextLost(); |
77 void OnSignalSyncPoint(const base::Closure& callback); | 77 void OnSignalSyncPoint(const base::Closure& callback); |
78 | 78 |
79 scoped_ptr<gles2::GLES2CmdHelper> gles2_helper_; | 79 scoped_ptr<gles2::GLES2CmdHelper> gles2_helper_; |
80 scoped_ptr<TransferBuffer> transfer_buffer_; | 80 scoped_ptr<TransferBuffer> transfer_buffer_; |
81 scoped_ptr<gles2::GLES2Implementation> gles2_implementation_; | 81 scoped_ptr<gles2::GLES2Implementation> gles2_implementation_; |
82 scoped_ptr<InProcessCommandBuffer> command_buffer_; | 82 scoped_ptr<InProcessCommandBuffer> command_buffer_; |
83 | 83 |
| 84 const GLInProcessContextSharedMemoryLimits mem_limits_; |
84 bool context_lost_; | 85 bool context_lost_; |
85 base::Closure context_lost_callback_; | 86 base::Closure context_lost_callback_; |
86 | 87 |
87 DISALLOW_COPY_AND_ASSIGN(GLInProcessContextImpl); | 88 DISALLOW_COPY_AND_ASSIGN(GLInProcessContextImpl); |
88 }; | 89 }; |
89 | 90 |
90 base::LazyInstance<base::Lock> g_all_shared_contexts_lock = | 91 base::LazyInstance<base::Lock> g_all_shared_contexts_lock = |
91 LAZY_INSTANCE_INITIALIZER; | 92 LAZY_INSTANCE_INITIALIZER; |
92 base::LazyInstance<std::set<GLInProcessContextImpl*> > g_all_shared_contexts = | 93 base::LazyInstance<std::set<GLInProcessContextImpl*> > g_all_shared_contexts = |
93 LAZY_INSTANCE_INITIALIZER; | 94 LAZY_INSTANCE_INITIALIZER; |
94 | 95 |
95 GLInProcessContextImpl::GLInProcessContextImpl() | 96 GLInProcessContextImpl::GLInProcessContextImpl( |
96 : context_lost_(false) {} | 97 const GLInProcessContextSharedMemoryLimits& mem_limits) |
| 98 : mem_limits_(mem_limits), context_lost_(false) { |
| 99 } |
97 | 100 |
98 GLInProcessContextImpl::~GLInProcessContextImpl() { | 101 GLInProcessContextImpl::~GLInProcessContextImpl() { |
99 { | 102 { |
100 base::AutoLock lock(g_all_shared_contexts_lock.Get()); | 103 base::AutoLock lock(g_all_shared_contexts_lock.Get()); |
101 g_all_shared_contexts.Get().erase(this); | 104 g_all_shared_contexts.Get().erase(this); |
102 } | 105 } |
103 Destroy(); | 106 Destroy(); |
104 } | 107 } |
105 | 108 |
106 gles2::GLES2Implementation* GLInProcessContextImpl::GetImplementation() { | 109 gles2::GLES2Implementation* GLInProcessContextImpl::GetImplementation() { |
107 return gles2_implementation_.get(); | 110 return gles2_implementation_.get(); |
108 } | 111 } |
109 | 112 |
| 113 size_t GLInProcessContextImpl::GetMappedMemoryLimit() { |
| 114 return mem_limits_.mapped_memory_reclaim_limit; |
| 115 } |
| 116 |
110 void GLInProcessContextImpl::SetContextLostCallback( | 117 void GLInProcessContextImpl::SetContextLostCallback( |
111 const base::Closure& callback) { | 118 const base::Closure& callback) { |
112 context_lost_callback_ = callback; | 119 context_lost_callback_ = callback; |
113 } | 120 } |
114 | 121 |
115 void GLInProcessContextImpl::OnContextLost() { | 122 void GLInProcessContextImpl::OnContextLost() { |
116 context_lost_ = true; | 123 context_lost_ = true; |
117 if (!context_lost_callback_.is_null()) { | 124 if (!context_lost_callback_.is_null()) { |
118 context_lost_callback_.Run(); | 125 context_lost_callback_.Run(); |
119 } | 126 } |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
174 attrib_vector, | 181 attrib_vector, |
175 gpu_preference, | 182 gpu_preference, |
176 wrapped_callback, | 183 wrapped_callback, |
177 share_command_buffer)) { | 184 share_command_buffer)) { |
178 LOG(ERROR) << "Failed to initialize InProcessCommmandBuffer"; | 185 LOG(ERROR) << "Failed to initialize InProcessCommmandBuffer"; |
179 return false; | 186 return false; |
180 } | 187 } |
181 | 188 |
182 // Create the GLES2 helper, which writes the command buffer protocol. | 189 // Create the GLES2 helper, which writes the command buffer protocol. |
183 gles2_helper_.reset(new gles2::GLES2CmdHelper(command_buffer_.get())); | 190 gles2_helper_.reset(new gles2::GLES2CmdHelper(command_buffer_.get())); |
184 if (!gles2_helper_->Initialize(kCommandBufferSize)) { | 191 if (!gles2_helper_->Initialize(mem_limits_.command_buffer_size)) { |
185 LOG(ERROR) << "Failed to initialize GLES2CmdHelper"; | 192 LOG(ERROR) << "Failed to initialize GLES2CmdHelper"; |
186 Destroy(); | 193 Destroy(); |
187 return false; | 194 return false; |
188 } | 195 } |
189 | 196 |
190 // Create a transfer buffer. | 197 // Create a transfer buffer. |
191 transfer_buffer_.reset(new TransferBuffer(gles2_helper_.get())); | 198 transfer_buffer_.reset(new TransferBuffer(gles2_helper_.get())); |
192 | 199 |
193 // Check for consistency. | 200 // Check for consistency. |
194 DCHECK(!attribs.bind_generates_resource); | 201 DCHECK(!attribs.bind_generates_resource); |
195 bool bind_generates_resource = false; | 202 bool bind_generates_resource = false; |
196 | 203 |
197 // Create the object exposing the OpenGL API. | 204 // Create the object exposing the OpenGL API. |
198 gles2_implementation_.reset(new gles2::GLES2Implementation( | 205 gles2_implementation_.reset(new gles2::GLES2Implementation( |
199 gles2_helper_.get(), | 206 gles2_helper_.get(), |
200 share_group, | 207 share_group, |
201 transfer_buffer_.get(), | 208 transfer_buffer_.get(), |
202 bind_generates_resource, | 209 bind_generates_resource, |
203 attribs.lose_context_when_out_of_memory, | 210 attribs.lose_context_when_out_of_memory, |
204 command_buffer_.get())); | 211 command_buffer_.get())); |
205 | 212 |
206 if (use_global_share_group) { | 213 if (use_global_share_group) { |
207 g_all_shared_contexts.Get().insert(this); | 214 g_all_shared_contexts.Get().insert(this); |
208 scoped_shared_context_lock.reset(); | 215 scoped_shared_context_lock.reset(); |
209 } | 216 } |
210 | 217 |
211 if (!gles2_implementation_->Initialize( | 218 if (!gles2_implementation_->Initialize( |
212 kStartTransferBufferSize, | 219 mem_limits_.start_transfer_buffer_size, |
213 kMinTransferBufferSize, | 220 mem_limits_.min_transfer_buffer_size, |
214 kMaxTransferBufferSize, | 221 mem_limits_.max_transfer_buffer_size, |
215 gles2::GLES2Implementation::kNoLimit)) { | 222 mem_limits_.mapped_memory_reclaim_limit)) { |
216 return false; | 223 return false; |
217 } | 224 } |
218 | 225 |
219 return true; | 226 return true; |
220 } | 227 } |
221 | 228 |
222 void GLInProcessContextImpl::Destroy() { | 229 void GLInProcessContextImpl::Destroy() { |
223 if (gles2_implementation_) { | 230 if (gles2_implementation_) { |
224 // First flush the context to ensure that any pending frees of resources | 231 // First flush the context to ensure that any pending frees of resources |
225 // are completed. Otherwise, if this context is part of a share group, | 232 // are completed. Otherwise, if this context is part of a share group, |
(...skipping 12 matching lines...) Expand all Loading... |
238 | 245 |
239 #if defined(OS_ANDROID) | 246 #if defined(OS_ANDROID) |
240 scoped_refptr<gfx::SurfaceTexture> | 247 scoped_refptr<gfx::SurfaceTexture> |
241 GLInProcessContextImpl::GetSurfaceTexture(uint32 stream_id) { | 248 GLInProcessContextImpl::GetSurfaceTexture(uint32 stream_id) { |
242 return command_buffer_->GetSurfaceTexture(stream_id); | 249 return command_buffer_->GetSurfaceTexture(stream_id); |
243 } | 250 } |
244 #endif | 251 #endif |
245 | 252 |
246 } // anonymous namespace | 253 } // anonymous namespace |
247 | 254 |
| 255 GLInProcessContextSharedMemoryLimits::GLInProcessContextSharedMemoryLimits() |
| 256 : command_buffer_size(kDefaultCommandBufferSize), |
| 257 start_transfer_buffer_size(kDefaultStartTransferBufferSize), |
| 258 min_transfer_buffer_size(kDefaultMinTransferBufferSize), |
| 259 max_transfer_buffer_size(kDefaultMaxTransferBufferSize), |
| 260 mapped_memory_reclaim_limit(gles2::GLES2Implementation::kNoLimit) { |
| 261 } |
| 262 |
| 263 // static |
248 GLInProcessContext* GLInProcessContext::Create( | 264 GLInProcessContext* GLInProcessContext::Create( |
249 scoped_refptr<gpu::InProcessCommandBuffer::Service> service, | 265 scoped_refptr<gpu::InProcessCommandBuffer::Service> service, |
250 scoped_refptr<gfx::GLSurface> surface, | 266 scoped_refptr<gfx::GLSurface> surface, |
251 bool is_offscreen, | 267 bool is_offscreen, |
252 gfx::AcceleratedWidget window, | 268 gfx::AcceleratedWidget window, |
253 const gfx::Size& size, | 269 const gfx::Size& size, |
254 GLInProcessContext* share_context, | 270 GLInProcessContext* share_context, |
255 bool use_global_share_group, | 271 bool use_global_share_group, |
256 const ::gpu::gles2::ContextCreationAttribHelper& attribs, | 272 const ::gpu::gles2::ContextCreationAttribHelper& attribs, |
257 gfx::GpuPreference gpu_preference) { | 273 gfx::GpuPreference gpu_preference, |
| 274 const GLInProcessContextSharedMemoryLimits& memory_limits) { |
258 DCHECK(!use_global_share_group || !share_context); | 275 DCHECK(!use_global_share_group || !share_context); |
259 if (surface.get()) { | 276 if (surface.get()) { |
260 DCHECK_EQ(surface->IsOffscreen(), is_offscreen); | 277 DCHECK_EQ(surface->IsOffscreen(), is_offscreen); |
261 DCHECK(surface->GetSize() == size); | 278 DCHECK(surface->GetSize() == size); |
262 DCHECK_EQ(gfx::kNullAcceleratedWidget, window); | 279 DCHECK_EQ(gfx::kNullAcceleratedWidget, window); |
263 } | 280 } |
264 | 281 |
265 scoped_ptr<GLInProcessContextImpl> context(new GLInProcessContextImpl()); | 282 scoped_ptr<GLInProcessContextImpl> context( |
| 283 new GLInProcessContextImpl(memory_limits)); |
266 if (!context->Initialize(surface, | 284 if (!context->Initialize(surface, |
267 is_offscreen, | 285 is_offscreen, |
268 use_global_share_group, | 286 use_global_share_group, |
269 share_context, | 287 share_context, |
270 window, | 288 window, |
271 size, | 289 size, |
272 attribs, | 290 attribs, |
273 gpu_preference, | 291 gpu_preference, |
274 service)) | 292 service)) |
275 return NULL; | 293 return NULL; |
276 | 294 |
277 return context.release(); | 295 return context.release(); |
278 } | 296 } |
279 | 297 |
280 } // namespace gpu | 298 } // namespace gpu |
OLD | NEW |