| 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 |