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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
46 static GpuMemoryBufferFactory* g_gpu_memory_buffer_factory = NULL; | 46 static GpuMemoryBufferFactory* g_gpu_memory_buffer_factory = NULL; |
47 | 47 |
48 class GLInProcessContextImpl | 48 class GLInProcessContextImpl |
49 : public GLInProcessContext, | 49 : public GLInProcessContext, |
50 public gles2::ImageFactory, | 50 public gles2::ImageFactory, |
51 public base::SupportsWeakPtr<GLInProcessContextImpl> { | 51 public base::SupportsWeakPtr<GLInProcessContextImpl> { |
52 public: | 52 public: |
53 explicit GLInProcessContextImpl(); | 53 explicit GLInProcessContextImpl(); |
54 virtual ~GLInProcessContextImpl(); | 54 virtual ~GLInProcessContextImpl(); |
55 | 55 |
56 bool Initialize(bool is_offscreen, | 56 bool Initialize(scoped_refptr<gfx::GLSurface> surface, |
| 57 bool is_offscreen, |
57 bool share_resources, | 58 bool share_resources, |
58 gfx::AcceleratedWidget window, | 59 gfx::AcceleratedWidget window, |
59 const gfx::Size& size, | 60 const gfx::Size& size, |
60 const char* allowed_extensions, | 61 const char* allowed_extensions, |
61 const int32* attrib_list, | 62 const GLInProcessContextAttribs& attribs, |
62 gfx::GpuPreference gpu_preference, | 63 gfx::GpuPreference gpu_preference); |
63 const base::Closure& context_lost_callback); | |
64 | 64 |
65 // GLInProcessContext implementation: | 65 // GLInProcessContext implementation: |
| 66 virtual void SetContextLostCallback(const base::Closure& callback) OVERRIDE; |
66 virtual void SignalSyncPoint(unsigned sync_point, | 67 virtual void SignalSyncPoint(unsigned sync_point, |
67 const base::Closure& callback) OVERRIDE; | 68 const base::Closure& callback) OVERRIDE; |
68 virtual void SignalQuery(unsigned query, const base::Closure& callback) | 69 virtual void SignalQuery(unsigned query, const base::Closure& callback) |
69 OVERRIDE; | 70 OVERRIDE; |
70 virtual gles2::GLES2Implementation* GetImplementation() OVERRIDE; | 71 virtual gles2::GLES2Implementation* GetImplementation() OVERRIDE; |
71 | 72 |
72 // ImageFactory implementation: | 73 // ImageFactory implementation: |
73 virtual scoped_ptr<gfx::GpuMemoryBuffer> CreateGpuMemoryBuffer( | 74 virtual scoped_ptr<gfx::GpuMemoryBuffer> CreateGpuMemoryBuffer( |
74 int width, int height, GLenum internalformat, | 75 int width, int height, GLenum internalformat, |
75 unsigned* image_id) OVERRIDE; | 76 unsigned* image_id) OVERRIDE; |
76 virtual void DeleteGpuMemoryBuffer(unsigned image_id) OVERRIDE; | 77 virtual void DeleteGpuMemoryBuffer(unsigned image_id) OVERRIDE; |
77 | 78 |
78 private: | 79 private: |
79 void Destroy(); | 80 void Destroy(); |
80 void PollQueryCallbacks(); | 81 void PollQueryCallbacks(); |
81 void CallQueryCallback(size_t index); | 82 void CallQueryCallback(size_t index); |
82 void OnContextLost(const base::Closure& callback); | 83 void OnContextLost(); |
83 void OnSignalSyncPoint(const base::Closure& callback); | 84 void OnSignalSyncPoint(const base::Closure& callback); |
84 | 85 |
85 scoped_ptr<gles2::GLES2CmdHelper> gles2_helper_; | 86 scoped_ptr<gles2::GLES2CmdHelper> gles2_helper_; |
86 scoped_ptr<TransferBuffer> transfer_buffer_; | 87 scoped_ptr<TransferBuffer> transfer_buffer_; |
87 scoped_ptr<gles2::GLES2Implementation> gles2_implementation_; | 88 scoped_ptr<gles2::GLES2Implementation> gles2_implementation_; |
88 scoped_ptr<InProcessCommandBuffer> command_buffer_; | 89 scoped_ptr<InProcessCommandBuffer> command_buffer_; |
89 | 90 |
90 typedef std::pair<unsigned, base::Closure> QueryCallback; | 91 typedef std::pair<unsigned, base::Closure> QueryCallback; |
91 std::vector<QueryCallback> query_callbacks_; | 92 std::vector<QueryCallback> query_callbacks_; |
92 | 93 |
93 unsigned int share_group_id_; | 94 unsigned int share_group_id_; |
94 bool context_lost_; | 95 bool context_lost_; |
| 96 base::Closure context_lost_callback_; |
95 | 97 |
96 DISALLOW_COPY_AND_ASSIGN(GLInProcessContextImpl); | 98 DISALLOW_COPY_AND_ASSIGN(GLInProcessContextImpl); |
97 }; | 99 }; |
98 | 100 |
99 base::LazyInstance<base::Lock> g_all_shared_contexts_lock = | 101 base::LazyInstance<base::Lock> g_all_shared_contexts_lock = |
100 LAZY_INSTANCE_INITIALIZER; | 102 LAZY_INSTANCE_INITIALIZER; |
101 base::LazyInstance<std::set<GLInProcessContextImpl*> > g_all_shared_contexts = | 103 base::LazyInstance<std::set<GLInProcessContextImpl*> > g_all_shared_contexts = |
102 LAZY_INSTANCE_INITIALIZER; | 104 LAZY_INSTANCE_INITIALIZER; |
103 | 105 |
104 size_t SharedContextCount() { | 106 size_t SharedContextCount() { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
140 DCHECK(!callback.is_null()); | 142 DCHECK(!callback.is_null()); |
141 base::Closure wrapped_callback = base::Bind( | 143 base::Closure wrapped_callback = base::Bind( |
142 &GLInProcessContextImpl::OnSignalSyncPoint, AsWeakPtr(), callback); | 144 &GLInProcessContextImpl::OnSignalSyncPoint, AsWeakPtr(), callback); |
143 command_buffer_->SignalSyncPoint(sync_point, wrapped_callback); | 145 command_buffer_->SignalSyncPoint(sync_point, wrapped_callback); |
144 } | 146 } |
145 | 147 |
146 gles2::GLES2Implementation* GLInProcessContextImpl::GetImplementation() { | 148 gles2::GLES2Implementation* GLInProcessContextImpl::GetImplementation() { |
147 return gles2_implementation_.get(); | 149 return gles2_implementation_.get(); |
148 } | 150 } |
149 | 151 |
150 void GLInProcessContextImpl::OnContextLost(const base::Closure& callback) { | 152 void GLInProcessContextImpl::SetContextLostCallback( |
| 153 const base::Closure& callback) { |
| 154 context_lost_callback_ = callback; |
| 155 } |
| 156 |
| 157 void GLInProcessContextImpl::OnContextLost() { |
151 context_lost_ = true; | 158 context_lost_ = true; |
152 callback.Run(); | 159 if (!context_lost_callback_.is_null()) { |
| 160 context_lost_callback_.Run(); |
| 161 } |
153 } | 162 } |
154 | 163 |
155 void GLInProcessContextImpl::OnSignalSyncPoint(const base::Closure& callback) { | 164 void GLInProcessContextImpl::OnSignalSyncPoint(const base::Closure& callback) { |
156 // TODO: Should it always trigger callbacks? | 165 // TODO: Should it always trigger callbacks? |
157 if (!context_lost_) | 166 if (!context_lost_) |
158 callback.Run(); | 167 callback.Run(); |
159 } | 168 } |
160 | 169 |
161 bool GLInProcessContextImpl::Initialize( | 170 bool GLInProcessContextImpl::Initialize( |
| 171 scoped_refptr<gfx::GLSurface> surface, |
162 bool is_offscreen, | 172 bool is_offscreen, |
163 bool share_resources, | 173 bool share_resources, |
164 gfx::AcceleratedWidget window, | 174 gfx::AcceleratedWidget window, |
165 const gfx::Size& size, | 175 const gfx::Size& size, |
166 const char* allowed_extensions, | 176 const char* allowed_extensions, |
167 const int32* attrib_list, | 177 const GLInProcessContextAttribs& attribs, |
168 gfx::GpuPreference gpu_preference, | 178 gfx::GpuPreference gpu_preference) { |
169 const base::Closure& context_lost_callback) { | |
170 DCHECK(size.width() >= 0 && size.height() >= 0); | 179 DCHECK(size.width() >= 0 && size.height() >= 0); |
171 | 180 |
172 std::vector<int32> attribs; | 181 const int32 ALPHA_SIZE = 0x3021; |
173 while (attrib_list) { | 182 const int32 BLUE_SIZE = 0x3022; |
174 int32 attrib = *attrib_list++; | 183 const int32 GREEN_SIZE = 0x3023; |
175 switch (attrib) { | 184 const int32 RED_SIZE = 0x3024; |
176 // Known attributes | 185 const int32 DEPTH_SIZE = 0x3025; |
177 case ALPHA_SIZE: | 186 const int32 STENCIL_SIZE = 0x3026; |
178 case BLUE_SIZE: | 187 const int32 SAMPLES = 0x3031; |
179 case GREEN_SIZE: | 188 const int32 SAMPLE_BUFFERS = 0x3032; |
180 case RED_SIZE: | 189 const int32 NONE = 0x3038; |
181 case DEPTH_SIZE: | 190 |
182 case STENCIL_SIZE: | 191 std::vector<int32> attrib_vector; |
183 case SAMPLES: | 192 if (attribs.alpha_size >= 0) { |
184 case SAMPLE_BUFFERS: | 193 attrib_vector.push_back(ALPHA_SIZE); |
185 attribs.push_back(attrib); | 194 attrib_vector.push_back(attribs.alpha_size); |
186 attribs.push_back(*attrib_list++); | |
187 break; | |
188 case NONE: | |
189 attribs.push_back(attrib); | |
190 attrib_list = NULL; | |
191 break; | |
192 default: | |
193 attribs.push_back(NONE); | |
194 attrib_list = NULL; | |
195 break; | |
196 } | |
197 } | 195 } |
| 196 if (attribs.blue_size >= 0) { |
| 197 attrib_vector.push_back(BLUE_SIZE); |
| 198 attrib_vector.push_back(attribs.blue_size); |
| 199 } |
| 200 if (attribs.green_size >= 0) { |
| 201 attrib_vector.push_back(GREEN_SIZE); |
| 202 attrib_vector.push_back(attribs.green_size); |
| 203 } |
| 204 if (attribs.red_size >= 0) { |
| 205 attrib_vector.push_back(RED_SIZE); |
| 206 attrib_vector.push_back(attribs.red_size); |
| 207 } |
| 208 if (attribs.depth_size >= 0) { |
| 209 attrib_vector.push_back(DEPTH_SIZE); |
| 210 attrib_vector.push_back(attribs.depth_size); |
| 211 } |
| 212 if (attribs.stencil_size >= 0) { |
| 213 attrib_vector.push_back(STENCIL_SIZE); |
| 214 attrib_vector.push_back(attribs.stencil_size); |
| 215 } |
| 216 if (attribs.samples >= 0) { |
| 217 attrib_vector.push_back(SAMPLES); |
| 218 attrib_vector.push_back(attribs.samples); |
| 219 } |
| 220 if (attribs.sample_buffers >= 0) { |
| 221 attrib_vector.push_back(SAMPLE_BUFFERS); |
| 222 attrib_vector.push_back(attribs.sample_buffers); |
| 223 } |
| 224 attrib_vector.push_back(NONE); |
198 | 225 |
199 base::Closure wrapped_callback = | 226 base::Closure wrapped_callback = |
200 base::Bind(&GLInProcessContextImpl::OnContextLost, | 227 base::Bind(&GLInProcessContextImpl::OnContextLost, AsWeakPtr()); |
201 AsWeakPtr(), | |
202 context_lost_callback); | |
203 command_buffer_.reset(new InProcessCommandBuffer()); | 228 command_buffer_.reset(new InProcessCommandBuffer()); |
204 | 229 |
205 scoped_ptr<base::AutoLock> scoped_shared_context_lock; | 230 scoped_ptr<base::AutoLock> scoped_shared_context_lock; |
206 scoped_refptr<gles2::ShareGroup> share_group; | 231 scoped_refptr<gles2::ShareGroup> share_group; |
207 if (share_resources) { | 232 if (share_resources) { |
208 scoped_shared_context_lock.reset( | 233 scoped_shared_context_lock.reset( |
209 new base::AutoLock(g_all_shared_contexts_lock.Get())); | 234 new base::AutoLock(g_all_shared_contexts_lock.Get())); |
210 for (std::set<GLInProcessContextImpl*>::const_iterator it = | 235 for (std::set<GLInProcessContextImpl*>::const_iterator it = |
211 g_all_shared_contexts.Get().begin(); | 236 g_all_shared_contexts.Get().begin(); |
212 it != g_all_shared_contexts.Get().end(); | 237 it != g_all_shared_contexts.Get().end(); |
213 it++) { | 238 it++) { |
214 const GLInProcessContextImpl* context = *it; | 239 const GLInProcessContextImpl* context = *it; |
215 if (!context->context_lost_) { | 240 if (!context->context_lost_) { |
216 share_group = context->gles2_implementation_->share_group(); | 241 share_group = context->gles2_implementation_->share_group(); |
217 DCHECK(share_group); | 242 DCHECK(share_group); |
218 share_group_id_ = context->share_group_id_; | 243 share_group_id_ = context->share_group_id_; |
219 break; | 244 break; |
220 } | 245 } |
221 share_group_id_ = std::max(share_group_id_, context->share_group_id_); | 246 share_group_id_ = std::max(share_group_id_, context->share_group_id_); |
222 } | 247 } |
223 if (!share_group && !++share_group_id_) | 248 if (!share_group && !++share_group_id_) |
224 ++share_group_id_; | 249 ++share_group_id_; |
225 } | 250 } |
226 if (!command_buffer_->Initialize(is_offscreen, | 251 if (!command_buffer_->Initialize(surface, |
227 share_resources, | 252 is_offscreen, |
228 window, | 253 share_resources, |
229 size, | 254 window, |
230 allowed_extensions, | 255 size, |
231 attribs, | 256 allowed_extensions, |
232 gpu_preference, | 257 attrib_vector, |
233 wrapped_callback, | 258 gpu_preference, |
234 share_group_id_)) { | 259 wrapped_callback, |
| 260 share_group_id_)) { |
235 LOG(INFO) << "Failed to initialize InProcessCommmandBuffer"; | 261 LOG(INFO) << "Failed to initialize InProcessCommmandBuffer"; |
236 return false; | 262 return false; |
237 } | 263 } |
238 | 264 |
239 // Create the GLES2 helper, which writes the command buffer protocol. | 265 // Create the GLES2 helper, which writes the command buffer protocol. |
240 gles2_helper_.reset(new gles2::GLES2CmdHelper(command_buffer_.get())); | 266 gles2_helper_.reset(new gles2::GLES2CmdHelper(command_buffer_.get())); |
241 if (!gles2_helper_->Initialize(kCommandBufferSize)) { | 267 if (!gles2_helper_->Initialize(kCommandBufferSize)) { |
242 LOG(INFO) << "Failed to initialize GLES2CmdHelper"; | 268 LOG(INFO) << "Failed to initialize GLES2CmdHelper"; |
243 Destroy(); | 269 Destroy(); |
244 return false; | 270 return false; |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
330 const base::Closure& callback) { | 356 const base::Closure& callback) { |
331 query_callbacks_.push_back(std::make_pair(query, callback)); | 357 query_callbacks_.push_back(std::make_pair(query, callback)); |
332 // If size > 1, there is already a poll callback pending. | 358 // If size > 1, there is already a poll callback pending. |
333 if (query_callbacks_.size() == 1) { | 359 if (query_callbacks_.size() == 1) { |
334 PollQueryCallbacks(); | 360 PollQueryCallbacks(); |
335 } | 361 } |
336 } | 362 } |
337 | 363 |
338 } // anonymous namespace | 364 } // anonymous namespace |
339 | 365 |
| 366 GLInProcessContextAttribs::GLInProcessContextAttribs() |
| 367 : alpha_size(-1), |
| 368 blue_size(-1), |
| 369 green_size(-1), |
| 370 red_size(-1), |
| 371 depth_size(-1), |
| 372 stencil_size(-1), |
| 373 samples(-1), |
| 374 sample_buffers(-1) {} |
| 375 |
340 // static | 376 // static |
341 GLInProcessContext* GLInProcessContext::CreateContext( | 377 GLInProcessContext* GLInProcessContext::CreateContext( |
342 bool is_offscreen, | 378 bool is_offscreen, |
343 gfx::AcceleratedWidget window, | 379 gfx::AcceleratedWidget window, |
344 const gfx::Size& size, | 380 const gfx::Size& size, |
345 bool share_resources, | 381 bool share_resources, |
346 const char* allowed_extensions, | 382 const char* allowed_extensions, |
347 const int32* attrib_list, | 383 const GLInProcessContextAttribs& attribs, |
348 gfx::GpuPreference gpu_preference, | 384 gfx::GpuPreference gpu_preference) { |
349 const base::Closure& callback) { | |
350 scoped_ptr<GLInProcessContextImpl> context( | 385 scoped_ptr<GLInProcessContextImpl> context( |
351 new GLInProcessContextImpl()); | 386 new GLInProcessContextImpl()); |
352 if (!context->Initialize( | 387 if (!context->Initialize( |
| 388 NULL /* surface */, |
353 is_offscreen, | 389 is_offscreen, |
354 share_resources, | 390 share_resources, |
355 window, | 391 window, |
356 size, | 392 size, |
357 allowed_extensions, | 393 allowed_extensions, |
358 attrib_list, | 394 attribs, |
359 gpu_preference, | 395 gpu_preference)) |
360 callback)) | |
361 return NULL; | 396 return NULL; |
362 | 397 |
363 return context.release(); | 398 return context.release(); |
| 399 } |
| 400 |
| 401 // static |
| 402 GLInProcessContext* GLInProcessContext::CreateWithSurface( |
| 403 scoped_refptr<gfx::GLSurface> surface, |
| 404 bool is_offscreen, |
| 405 const gfx::Size& size, |
| 406 bool share_resources, |
| 407 const char* allowed_extensions, |
| 408 const GLInProcessContextAttribs& attribs, |
| 409 gfx::GpuPreference gpu_preference) { |
| 410 scoped_ptr<GLInProcessContextImpl> context( |
| 411 new GLInProcessContextImpl()); |
| 412 if (!context->Initialize( |
| 413 surface, |
| 414 is_offscreen, |
| 415 share_resources, |
| 416 NULL /* window */, |
| 417 size, |
| 418 allowed_extensions, |
| 419 attribs, |
| 420 gpu_preference)) |
| 421 return NULL; |
| 422 |
| 423 return context.release(); |
364 } | 424 } |
365 | 425 |
366 // static | 426 // static |
367 void GLInProcessContext::SetGpuMemoryBufferFactory( | 427 void GLInProcessContext::SetGpuMemoryBufferFactory( |
368 GpuMemoryBufferFactory* factory) { | 428 GpuMemoryBufferFactory* factory) { |
369 DCHECK_EQ(0u, SharedContextCount()); | 429 DCHECK_EQ(0u, SharedContextCount()); |
370 g_gpu_memory_buffer_factory = factory; | 430 g_gpu_memory_buffer_factory = factory; |
371 } | 431 } |
372 | 432 |
373 } // namespace gpu | 433 } // namespace gpu |
OLD | NEW |