Revert "Reland c91b178b07b0d - Delete dead signin code (SigninGlobalError)"
[chromium-blink-merge.git] / gpu / command_buffer / client / gl_in_process_context.cc
blob3b32c4815eca63a30a1a753116f50f73ca4234a5
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.
5 #include "gpu/command_buffer/client/gl_in_process_context.h"
7 #include <set>
8 #include <utility>
9 #include <vector>
11 #include <GLES2/gl2.h>
12 #ifndef GL_GLEXT_PROTOTYPES
13 #define GL_GLEXT_PROTOTYPES 1
14 #endif
15 #include <GLES2/gl2ext.h>
16 #include <GLES2/gl2extchromium.h>
18 #include "base/bind.h"
19 #include "base/bind_helpers.h"
20 #include "base/lazy_instance.h"
21 #include "base/logging.h"
22 #include "base/memory/scoped_ptr.h"
23 #include "base/memory/weak_ptr.h"
24 #include "base/message_loop/message_loop.h"
25 #include "gpu/command_buffer/client/gles2_cmd_helper.h"
26 #include "gpu/command_buffer/client/gles2_implementation.h"
27 #include "gpu/command_buffer/client/transfer_buffer.h"
28 #include "gpu/command_buffer/common/command_buffer.h"
29 #include "gpu/command_buffer/common/constants.h"
30 #include "ui/gfx/geometry/size.h"
31 #include "ui/gl/gl_image.h"
33 #if defined(OS_ANDROID)
34 #include "ui/gl/android/surface_texture.h"
35 #endif
37 namespace gpu {
39 namespace {
41 const int32 kDefaultCommandBufferSize = 1024 * 1024;
42 const unsigned int kDefaultStartTransferBufferSize = 4 * 1024 * 1024;
43 const unsigned int kDefaultMinTransferBufferSize = 1 * 256 * 1024;
44 const unsigned int kDefaultMaxTransferBufferSize = 16 * 1024 * 1024;
46 class GLInProcessContextImpl
47 : public GLInProcessContext,
48 public base::SupportsWeakPtr<GLInProcessContextImpl> {
49 public:
50 explicit GLInProcessContextImpl(
51 const GLInProcessContextSharedMemoryLimits& mem_limits);
52 ~GLInProcessContextImpl() override;
54 bool Initialize(scoped_refptr<gfx::GLSurface> surface,
55 bool is_offscreen,
56 bool use_global_share_group,
57 GLInProcessContext* share_context,
58 gfx::AcceleratedWidget window,
59 const gfx::Size& size,
60 const gpu::gles2::ContextCreationAttribHelper& attribs,
61 gfx::GpuPreference gpu_preference,
62 const scoped_refptr<InProcessCommandBuffer::Service>& service,
63 GpuMemoryBufferManager* gpu_memory_buffer_manager,
64 ImageFactory* image_factory);
66 // GLInProcessContext implementation:
67 void SetContextLostCallback(const base::Closure& callback) override;
68 gles2::GLES2Implementation* GetImplementation() override;
69 size_t GetMappedMemoryLimit() override;
70 void SetLock(base::Lock* lock) override;
72 #if defined(OS_ANDROID)
73 scoped_refptr<gfx::SurfaceTexture> GetSurfaceTexture(
74 uint32 stream_id) override;
75 #endif
77 private:
78 void Destroy();
79 void OnContextLost();
80 void OnSignalSyncPoint(const base::Closure& callback);
82 scoped_ptr<gles2::GLES2CmdHelper> gles2_helper_;
83 scoped_ptr<TransferBuffer> transfer_buffer_;
84 scoped_ptr<gles2::GLES2Implementation> gles2_implementation_;
85 scoped_ptr<InProcessCommandBuffer> command_buffer_;
87 const GLInProcessContextSharedMemoryLimits mem_limits_;
88 bool context_lost_;
89 base::Closure context_lost_callback_;
90 base::Lock* lock_;
92 DISALLOW_COPY_AND_ASSIGN(GLInProcessContextImpl);
95 base::LazyInstance<base::Lock> g_all_shared_contexts_lock =
96 LAZY_INSTANCE_INITIALIZER;
97 base::LazyInstance<std::set<GLInProcessContextImpl*> > g_all_shared_contexts =
98 LAZY_INSTANCE_INITIALIZER;
100 GLInProcessContextImpl::GLInProcessContextImpl(
101 const GLInProcessContextSharedMemoryLimits& mem_limits)
102 : mem_limits_(mem_limits), context_lost_(false), lock_(nullptr) {
105 GLInProcessContextImpl::~GLInProcessContextImpl() {
107 base::AutoLock lock(g_all_shared_contexts_lock.Get());
108 g_all_shared_contexts.Get().erase(this);
110 Destroy();
113 gles2::GLES2Implementation* GLInProcessContextImpl::GetImplementation() {
114 return gles2_implementation_.get();
117 size_t GLInProcessContextImpl::GetMappedMemoryLimit() {
118 return mem_limits_.mapped_memory_reclaim_limit;
121 void GLInProcessContextImpl::SetLock(base::Lock* lock) {
122 command_buffer_->SetLock(lock);
123 lock_ = lock;
126 void GLInProcessContextImpl::SetContextLostCallback(
127 const base::Closure& callback) {
128 context_lost_callback_ = callback;
131 void GLInProcessContextImpl::OnContextLost() {
132 scoped_ptr<base::AutoLock> lock;
133 if (lock_)
134 lock.reset(new base::AutoLock(*lock_));
135 context_lost_ = true;
136 if (!context_lost_callback_.is_null()) {
137 context_lost_callback_.Run();
141 bool GLInProcessContextImpl::Initialize(
142 scoped_refptr<gfx::GLSurface> surface,
143 bool is_offscreen,
144 bool use_global_share_group,
145 GLInProcessContext* share_context,
146 gfx::AcceleratedWidget window,
147 const gfx::Size& size,
148 const gles2::ContextCreationAttribHelper& attribs,
149 gfx::GpuPreference gpu_preference,
150 const scoped_refptr<InProcessCommandBuffer::Service>& service,
151 GpuMemoryBufferManager* gpu_memory_buffer_manager,
152 ImageFactory* image_factory) {
153 DCHECK(!use_global_share_group || !share_context);
154 DCHECK(size.width() >= 0 && size.height() >= 0);
156 std::vector<int32> attrib_vector;
157 attribs.Serialize(&attrib_vector);
159 base::Closure wrapped_callback =
160 base::Bind(&GLInProcessContextImpl::OnContextLost, AsWeakPtr());
161 command_buffer_.reset(new InProcessCommandBuffer(service));
163 scoped_ptr<base::AutoLock> scoped_shared_context_lock;
164 scoped_refptr<gles2::ShareGroup> share_group;
165 InProcessCommandBuffer* share_command_buffer = NULL;
166 if (use_global_share_group) {
167 scoped_shared_context_lock.reset(
168 new base::AutoLock(g_all_shared_contexts_lock.Get()));
169 for (std::set<GLInProcessContextImpl*>::const_iterator it =
170 g_all_shared_contexts.Get().begin();
171 it != g_all_shared_contexts.Get().end();
172 it++) {
173 const GLInProcessContextImpl* context = *it;
174 if (!context->context_lost_) {
175 share_group = context->gles2_implementation_->share_group();
176 share_command_buffer = context->command_buffer_.get();
177 DCHECK(share_group.get());
178 DCHECK(share_command_buffer);
179 break;
182 } else if (share_context) {
183 GLInProcessContextImpl* impl =
184 static_cast<GLInProcessContextImpl*>(share_context);
185 share_group = impl->gles2_implementation_->share_group();
186 share_command_buffer = impl->command_buffer_.get();
187 DCHECK(share_group.get());
188 DCHECK(share_command_buffer);
191 if (!command_buffer_->Initialize(surface,
192 is_offscreen,
193 window,
194 size,
195 attrib_vector,
196 gpu_preference,
197 wrapped_callback,
198 share_command_buffer,
199 gpu_memory_buffer_manager,
200 image_factory)) {
201 LOG(ERROR) << "Failed to initialize InProcessCommmandBuffer";
202 return false;
205 // Create the GLES2 helper, which writes the command buffer protocol.
206 gles2_helper_.reset(new gles2::GLES2CmdHelper(command_buffer_.get()));
207 if (!gles2_helper_->Initialize(mem_limits_.command_buffer_size)) {
208 LOG(ERROR) << "Failed to initialize GLES2CmdHelper";
209 Destroy();
210 return false;
213 // Create a transfer buffer.
214 transfer_buffer_.reset(new TransferBuffer(gles2_helper_.get()));
216 // Check for consistency.
217 DCHECK(!attribs.bind_generates_resource);
218 const bool bind_generates_resource = false;
219 const bool support_client_side_arrays = false;
221 // Create the object exposing the OpenGL API.
222 gles2_implementation_.reset(
223 new gles2::GLES2Implementation(gles2_helper_.get(),
224 share_group.get(),
225 transfer_buffer_.get(),
226 bind_generates_resource,
227 attribs.lose_context_when_out_of_memory,
228 support_client_side_arrays,
229 command_buffer_.get()));
231 if (use_global_share_group) {
232 g_all_shared_contexts.Get().insert(this);
233 scoped_shared_context_lock.reset();
236 if (!gles2_implementation_->Initialize(
237 mem_limits_.start_transfer_buffer_size,
238 mem_limits_.min_transfer_buffer_size,
239 mem_limits_.max_transfer_buffer_size,
240 mem_limits_.mapped_memory_reclaim_limit)) {
241 return false;
244 return true;
247 void GLInProcessContextImpl::Destroy() {
248 if (gles2_implementation_) {
249 // First flush the context to ensure that any pending frees of resources
250 // are completed. Otherwise, if this context is part of a share group,
251 // those resources might leak. Also, any remaining side effects of commands
252 // issued on this context might not be visible to other contexts in the
253 // share group.
254 gles2_implementation_->Flush();
256 gles2_implementation_.reset();
259 transfer_buffer_.reset();
260 gles2_helper_.reset();
261 command_buffer_.reset();
264 #if defined(OS_ANDROID)
265 scoped_refptr<gfx::SurfaceTexture>
266 GLInProcessContextImpl::GetSurfaceTexture(uint32 stream_id) {
267 return command_buffer_->GetSurfaceTexture(stream_id);
269 #endif
271 } // anonymous namespace
273 GLInProcessContextSharedMemoryLimits::GLInProcessContextSharedMemoryLimits()
274 : command_buffer_size(kDefaultCommandBufferSize),
275 start_transfer_buffer_size(kDefaultStartTransferBufferSize),
276 min_transfer_buffer_size(kDefaultMinTransferBufferSize),
277 max_transfer_buffer_size(kDefaultMaxTransferBufferSize),
278 mapped_memory_reclaim_limit(gles2::GLES2Implementation::kNoLimit) {
281 // static
282 GLInProcessContext* GLInProcessContext::Create(
283 scoped_refptr<gpu::InProcessCommandBuffer::Service> service,
284 scoped_refptr<gfx::GLSurface> surface,
285 bool is_offscreen,
286 gfx::AcceleratedWidget window,
287 const gfx::Size& size,
288 GLInProcessContext* share_context,
289 bool use_global_share_group,
290 const ::gpu::gles2::ContextCreationAttribHelper& attribs,
291 gfx::GpuPreference gpu_preference,
292 const GLInProcessContextSharedMemoryLimits& memory_limits,
293 GpuMemoryBufferManager* gpu_memory_buffer_manager,
294 ImageFactory* image_factory) {
295 DCHECK(!use_global_share_group || !share_context);
296 if (surface.get()) {
297 DCHECK_EQ(surface->IsOffscreen(), is_offscreen);
298 DCHECK(surface->GetSize() == size);
299 DCHECK_EQ(gfx::kNullAcceleratedWidget, window);
302 scoped_ptr<GLInProcessContextImpl> context(
303 new GLInProcessContextImpl(memory_limits));
304 if (!context->Initialize(surface,
305 is_offscreen,
306 use_global_share_group,
307 share_context,
308 window,
309 size,
310 attribs,
311 gpu_preference,
312 service,
313 gpu_memory_buffer_manager,
314 image_factory))
315 return NULL;
317 return context.release();
320 } // namespace gpu