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 "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h" | 5 #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h" |
6 | 6 |
7 #include "third_party/khronos/GLES2/gl2.h" | 7 #include "third_party/khronos/GLES2/gl2.h" |
8 #ifndef GL_GLEXT_PROTOTYPES | 8 #ifndef GL_GLEXT_PROTOTYPES |
9 #define GL_GLEXT_PROTOTYPES 1 | 9 #define GL_GLEXT_PROTOTYPES 1 |
10 #endif | 10 #endif |
11 #include "third_party/khronos/GLES2/gl2ext.h" | 11 #include "third_party/khronos/GLES2/gl2ext.h" |
12 | 12 |
13 #include <algorithm> | 13 #include <algorithm> |
14 #include <map> | 14 #include <map> |
15 | 15 |
16 #include "base/atomicops.h" | 16 #include "base/atomicops.h" |
17 #include "base/bind.h" | 17 #include "base/bind.h" |
18 #include "base/command_line.h" | 18 #include "base/command_line.h" |
19 #include "base/debug/trace_event.h" | 19 #include "base/debug/trace_event.h" |
20 #include "base/lazy_instance.h" | 20 #include "base/lazy_instance.h" |
21 #include "base/logging.h" | 21 #include "base/logging.h" |
22 #include "base/message_loop/message_loop.h" | 22 #include "base/message_loop/message_loop.h" |
23 #include "base/metrics/field_trial.h" | 23 #include "base/metrics/field_trial.h" |
24 #include "base/metrics/histogram.h" | 24 #include "base/metrics/histogram.h" |
25 #include "base/synchronization/lock.h" | |
26 #include "content/common/gpu/client/gpu_channel_host.h" | 25 #include "content/common/gpu/client/gpu_channel_host.h" |
27 #include "content/public/common/content_constants.h" | 26 #include "content/public/common/content_constants.h" |
28 #include "content/public/common/content_switches.h" | 27 #include "content/public/common/content_switches.h" |
29 #include "gpu/GLES2/gl2extchromium.h" | 28 #include "gpu/GLES2/gl2extchromium.h" |
30 #include "gpu/command_buffer/client/gles2_cmd_helper.h" | 29 #include "gpu/command_buffer/client/gles2_cmd_helper.h" |
31 #include "gpu/command_buffer/client/gles2_implementation.h" | 30 #include "gpu/command_buffer/client/gles2_implementation.h" |
32 #include "gpu/command_buffer/client/gles2_lib.h" | 31 #include "gpu/command_buffer/client/gles2_lib.h" |
33 #include "gpu/command_buffer/client/gles2_trace_implementation.h" | 32 #include "gpu/command_buffer/client/gles2_trace_implementation.h" |
34 #include "gpu/command_buffer/client/transfer_buffer.h" | 33 #include "gpu/command_buffer/client/transfer_buffer.h" |
35 #include "gpu/command_buffer/common/constants.h" | 34 #include "gpu/command_buffer/common/constants.h" |
36 #include "gpu/command_buffer/common/gpu_memory_allocation.h" | 35 #include "gpu/command_buffer/common/gpu_memory_allocation.h" |
37 #include "gpu/command_buffer/common/mailbox.h" | 36 #include "gpu/command_buffer/common/mailbox.h" |
38 #include "gpu/skia_bindings/gl_bindings_skia_cmd_buffer.h" | 37 #include "gpu/skia_bindings/gl_bindings_skia_cmd_buffer.h" |
39 #include "third_party/skia/include/core/SkTypes.h" | 38 #include "third_party/skia/include/core/SkTypes.h" |
40 | 39 |
41 namespace content { | 40 namespace content { |
42 | 41 |
43 namespace { | 42 namespace { |
44 | 43 |
45 static base::LazyInstance<base::Lock>::Leaky | 44 static base::LazyInstance<base::Lock>::Leaky |
46 g_all_shared_contexts_lock = LAZY_INSTANCE_INITIALIZER; | 45 g_default_share_groups_lock = LAZY_INSTANCE_INITIALIZER; |
47 | 46 |
48 typedef std::multimap<GpuChannelHost*, WebGraphicsContext3DCommandBufferImpl*> | 47 typedef std::map<GpuChannelHost*, |
49 ContextMap; | 48 scoped_refptr<WebGraphicsContext3DCommandBufferImpl::ShareGroup> > |
50 static base::LazyInstance<ContextMap> g_all_shared_contexts = | 49 ShareGroupMap; |
| 50 static base::LazyInstance<ShareGroupMap> g_default_share_groups = |
51 LAZY_INSTANCE_INITIALIZER; | 51 LAZY_INSTANCE_INITIALIZER; |
52 | 52 |
| 53 scoped_refptr<WebGraphicsContext3DCommandBufferImpl::ShareGroup> |
| 54 GetDefaultShareGroupForHost(GpuChannelHost* host) { |
| 55 base::AutoLock lock(g_default_share_groups_lock.Get()); |
| 56 |
| 57 ShareGroupMap& share_groups = g_default_share_groups.Get(); |
| 58 ShareGroupMap::iterator it = share_groups.find(host); |
| 59 if (it == share_groups.end()) { |
| 60 scoped_refptr<WebGraphicsContext3DCommandBufferImpl::ShareGroup> group = |
| 61 new WebGraphicsContext3DCommandBufferImpl::ShareGroup(); |
| 62 share_groups[host] = group; |
| 63 return group; |
| 64 } |
| 65 return it->second; |
| 66 } |
| 67 |
53 uint32_t GenFlushID() { | 68 uint32_t GenFlushID() { |
54 static base::subtle::Atomic32 flush_id = 0; | 69 static base::subtle::Atomic32 flush_id = 0; |
55 | 70 |
56 base::subtle::Atomic32 my_id = base::subtle::Barrier_AtomicIncrement( | 71 base::subtle::Atomic32 my_id = base::subtle::Barrier_AtomicIncrement( |
57 &flush_id, 1); | 72 &flush_id, 1); |
58 return static_cast<uint32_t>(my_id); | 73 return static_cast<uint32_t>(my_id); |
59 } | 74 } |
60 | 75 |
61 // Singleton used to initialize and terminate the gles2 library. | 76 // Singleton used to initialize and terminate the gles2 library. |
62 class GLES2Initializer { | 77 class GLES2Initializer { |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
195 graphics_context_->OnErrorMessage(msg, id); | 210 graphics_context_->OnErrorMessage(msg, id); |
196 } | 211 } |
197 | 212 |
198 WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits::SharedMemoryLimits() | 213 WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits::SharedMemoryLimits() |
199 : command_buffer_size(kDefaultCommandBufferSize), | 214 : command_buffer_size(kDefaultCommandBufferSize), |
200 start_transfer_buffer_size(kDefaultStartTransferBufferSize), | 215 start_transfer_buffer_size(kDefaultStartTransferBufferSize), |
201 min_transfer_buffer_size(kDefaultMinTransferBufferSize), | 216 min_transfer_buffer_size(kDefaultMinTransferBufferSize), |
202 max_transfer_buffer_size(kDefaultMaxTransferBufferSize), | 217 max_transfer_buffer_size(kDefaultMaxTransferBufferSize), |
203 mapped_memory_reclaim_limit(gpu::gles2::GLES2Implementation::kNoLimit) {} | 218 mapped_memory_reclaim_limit(gpu::gles2::GLES2Implementation::kNoLimit) {} |
204 | 219 |
| 220 WebGraphicsContext3DCommandBufferImpl::ShareGroup::ShareGroup() { |
| 221 } |
| 222 |
| 223 WebGraphicsContext3DCommandBufferImpl::ShareGroup::~ShareGroup() { |
| 224 DCHECK(contexts_.empty()); |
| 225 } |
| 226 |
205 WebGraphicsContext3DCommandBufferImpl::WebGraphicsContext3DCommandBufferImpl( | 227 WebGraphicsContext3DCommandBufferImpl::WebGraphicsContext3DCommandBufferImpl( |
206 int surface_id, | 228 int surface_id, |
207 const GURL& active_url, | 229 const GURL& active_url, |
208 GpuChannelHost* host, | 230 GpuChannelHost* host, |
209 const Attributes& attributes, | 231 const Attributes& attributes, |
210 bool bind_generates_resources, | 232 bool bind_generates_resources, |
211 const SharedMemoryLimits& limits) | 233 const SharedMemoryLimits& limits, |
| 234 WebGraphicsContext3DCommandBufferImpl* share_context) |
212 : initialize_failed_(false), | 235 : initialize_failed_(false), |
213 visible_(false), | 236 visible_(false), |
214 host_(host), | 237 host_(host), |
215 surface_id_(surface_id), | 238 surface_id_(surface_id), |
216 active_url_(active_url), | 239 active_url_(active_url), |
217 context_lost_callback_(0), | 240 context_lost_callback_(0), |
218 context_lost_reason_(GL_NO_ERROR), | 241 context_lost_reason_(GL_NO_ERROR), |
219 error_message_callback_(0), | 242 error_message_callback_(0), |
220 attributes_(attributes), | 243 attributes_(attributes), |
221 gpu_preference_(attributes.preferDiscreteGPU ? gfx::PreferDiscreteGpu | 244 gpu_preference_(attributes.preferDiscreteGPU ? gfx::PreferDiscreteGpu |
222 : gfx::PreferIntegratedGpu), | 245 : gfx::PreferIntegratedGpu), |
223 weak_ptr_factory_(this), | 246 weak_ptr_factory_(this), |
224 initialized_(false), | 247 initialized_(false), |
225 gl_(NULL), | 248 gl_(NULL), |
226 bind_generates_resources_(bind_generates_resources), | 249 bind_generates_resources_(bind_generates_resources), |
227 mem_limits_(limits), | 250 mem_limits_(limits), |
228 flush_id_(0) { | 251 flush_id_(0) { |
| 252 if (share_context) { |
| 253 DCHECK(!attributes_.shareResources); |
| 254 share_group_ = share_context->share_group_; |
| 255 } else { |
| 256 share_group_ = attributes_.shareResources |
| 257 ? GetDefaultShareGroupForHost(host) |
| 258 : scoped_refptr<WebGraphicsContext3DCommandBufferImpl::ShareGroup>( |
| 259 new ShareGroup()); |
| 260 } |
229 } | 261 } |
230 | 262 |
231 WebGraphicsContext3DCommandBufferImpl:: | 263 WebGraphicsContext3DCommandBufferImpl:: |
232 ~WebGraphicsContext3DCommandBufferImpl() { | 264 ~WebGraphicsContext3DCommandBufferImpl() { |
233 if (real_gl_) { | 265 if (real_gl_) { |
234 real_gl_->SetErrorMessageCallback(NULL); | 266 real_gl_->SetErrorMessageCallback(NULL); |
235 } | 267 } |
236 | 268 |
237 Destroy(); | 269 Destroy(); |
238 } | 270 } |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
288 attributes_.stencil = pvalues[2] > 0; | 320 attributes_.stencil = pvalues[2] > 0; |
289 attributes_.antialias = pvalues[3] > 0; | 321 attributes_.antialias = pvalues[3] > 0; |
290 } | 322 } |
291 | 323 |
292 visible_ = true; | 324 visible_ = true; |
293 initialized_ = true; | 325 initialized_ = true; |
294 return true; | 326 return true; |
295 } | 327 } |
296 | 328 |
297 bool WebGraphicsContext3DCommandBufferImpl::InitializeCommandBuffer( | 329 bool WebGraphicsContext3DCommandBufferImpl::InitializeCommandBuffer( |
298 bool onscreen) { | 330 bool onscreen, WebGraphicsContext3DCommandBufferImpl* share_context) { |
299 if (!host_.get()) | 331 if (!host_.get()) |
300 return false; | 332 return false; |
301 // We need to lock g_all_shared_contexts to ensure that the context we picked | 333 |
302 // for our share group isn't deleted. | 334 CommandBufferProxyImpl* share_group_command_buffer = NULL; |
303 // (There's also a lock in our destructor.) | 335 |
304 base::AutoLock lock(g_all_shared_contexts_lock.Get()); | 336 if (share_context) { |
305 CommandBufferProxyImpl* share_group = NULL; | 337 share_group_command_buffer = share_context->command_buffer_.get(); |
306 if (attributes_.shareResources) { | |
307 ContextMap& all_contexts = g_all_shared_contexts.Get(); | |
308 ContextMap::const_iterator it = all_contexts.find(host_.get()); | |
309 if (it != all_contexts.end()) | |
310 share_group = it->second->command_buffer_.get(); | |
311 } | 338 } |
312 | 339 |
313 std::vector<int32> attribs; | 340 std::vector<int32> attribs; |
314 attribs.push_back(ALPHA_SIZE); | 341 attribs.push_back(ALPHA_SIZE); |
315 attribs.push_back(attributes_.alpha ? 8 : 0); | 342 attribs.push_back(attributes_.alpha ? 8 : 0); |
316 attribs.push_back(DEPTH_SIZE); | 343 attribs.push_back(DEPTH_SIZE); |
317 attribs.push_back(attributes_.depth ? 24 : 0); | 344 attribs.push_back(attributes_.depth ? 24 : 0); |
318 attribs.push_back(STENCIL_SIZE); | 345 attribs.push_back(STENCIL_SIZE); |
319 attribs.push_back(attributes_.stencil ? 8 : 0); | 346 attribs.push_back(attributes_.stencil ? 8 : 0); |
320 attribs.push_back(SAMPLES); | 347 attribs.push_back(SAMPLES); |
321 attribs.push_back(attributes_.antialias ? 4 : 0); | 348 attribs.push_back(attributes_.antialias ? 4 : 0); |
322 attribs.push_back(SAMPLE_BUFFERS); | 349 attribs.push_back(SAMPLE_BUFFERS); |
323 attribs.push_back(attributes_.antialias ? 1 : 0); | 350 attribs.push_back(attributes_.antialias ? 1 : 0); |
324 attribs.push_back(FAIL_IF_MAJOR_PERF_CAVEAT); | 351 attribs.push_back(FAIL_IF_MAJOR_PERF_CAVEAT); |
325 attribs.push_back(attributes_.failIfMajorPerformanceCaveat ? 1 : 0); | 352 attribs.push_back(attributes_.failIfMajorPerformanceCaveat ? 1 : 0); |
326 attribs.push_back(NONE); | 353 attribs.push_back(NONE); |
327 | 354 |
328 // Create a proxy to a command buffer in the GPU process. | 355 // Create a proxy to a command buffer in the GPU process. |
329 if (onscreen) { | 356 if (onscreen) { |
330 command_buffer_.reset(host_->CreateViewCommandBuffer( | 357 command_buffer_.reset(host_->CreateViewCommandBuffer( |
331 surface_id_, | 358 surface_id_, |
332 share_group, | 359 share_group_command_buffer, |
333 attribs, | 360 attribs, |
334 active_url_, | 361 active_url_, |
335 gpu_preference_)); | 362 gpu_preference_)); |
336 } else { | 363 } else { |
337 command_buffer_.reset(host_->CreateOffscreenCommandBuffer( | 364 command_buffer_.reset(host_->CreateOffscreenCommandBuffer( |
338 gfx::Size(1, 1), | 365 gfx::Size(1, 1), |
339 share_group, | 366 share_group_command_buffer, |
340 attribs, | 367 attribs, |
341 active_url_, | 368 active_url_, |
342 gpu_preference_)); | 369 gpu_preference_)); |
343 } | 370 } |
344 | 371 |
345 if (!command_buffer_) | 372 if (!command_buffer_) |
346 return false; | 373 return false; |
347 | 374 |
348 // Initialize the command buffer. | 375 // Initialize the command buffer. |
349 return command_buffer_->Initialize(); | 376 return command_buffer_->Initialize(); |
350 } | 377 } |
351 | 378 |
352 bool WebGraphicsContext3DCommandBufferImpl::CreateContext( | 379 bool WebGraphicsContext3DCommandBufferImpl::CreateContext(bool onscreen) { |
353 bool onscreen) { | |
354 // Ensure the gles2 library is initialized first in a thread safe way. | 380 // Ensure the gles2 library is initialized first in a thread safe way. |
355 g_gles2_initializer.Get(); | 381 g_gles2_initializer.Get(); |
356 | 382 |
357 if (!command_buffer_ && | 383 scoped_refptr<gpu::gles2::ShareGroup> gles2_share_group; |
358 !InitializeCommandBuffer(onscreen)) { | 384 |
359 return false; | 385 scoped_ptr<base::AutoLock> share_group_lock; |
| 386 bool add_to_share_group = false; |
| 387 if (!command_buffer_) { |
| 388 WebGraphicsContext3DCommandBufferImpl* share_context = NULL; |
| 389 |
| 390 share_group_lock.reset(new base::AutoLock(share_group_->lock())); |
| 391 share_context = share_group_->GetAnyContextLocked(); |
| 392 |
| 393 if (!InitializeCommandBuffer(onscreen, share_context)) |
| 394 return false; |
| 395 |
| 396 if (share_context) |
| 397 gles2_share_group = share_context->GetImplementation()->share_group(); |
| 398 |
| 399 add_to_share_group = true; |
360 } | 400 } |
361 | 401 |
362 // Create the GLES2 helper, which writes the command buffer protocol. | 402 // Create the GLES2 helper, which writes the command buffer protocol. |
363 gles2_helper_.reset(new gpu::gles2::GLES2CmdHelper(command_buffer_.get())); | 403 gles2_helper_.reset(new gpu::gles2::GLES2CmdHelper(command_buffer_.get())); |
364 if (!gles2_helper_->Initialize(mem_limits_.command_buffer_size)) | 404 if (!gles2_helper_->Initialize(mem_limits_.command_buffer_size)) |
365 return false; | 405 return false; |
366 | 406 |
367 if (attributes_.noAutomaticFlushes) | 407 if (attributes_.noAutomaticFlushes) |
368 gles2_helper_->SetAutomaticFlushes(false); | 408 gles2_helper_->SetAutomaticFlushes(false); |
369 | 409 |
370 // Create a transfer buffer used to copy resources between the renderer | 410 // Create a transfer buffer used to copy resources between the renderer |
371 // process and the GPU process. | 411 // process and the GPU process. |
372 transfer_buffer_ .reset(new gpu::TransferBuffer(gles2_helper_.get())); | 412 transfer_buffer_ .reset(new gpu::TransferBuffer(gles2_helper_.get())); |
373 | 413 |
374 DCHECK(host_.get()); | 414 DCHECK(host_.get()); |
375 scoped_ptr<base::AutoLock> lock; | |
376 scoped_refptr<gpu::gles2::ShareGroup> share_group; | |
377 if (attributes_.shareResources) { | |
378 // Make sure two clients don't try to create a new ShareGroup | |
379 // simultaneously. | |
380 lock.reset(new base::AutoLock(g_all_shared_contexts_lock.Get())); | |
381 ContextMap& all_contexts = g_all_shared_contexts.Get(); | |
382 ContextMap::const_iterator it = all_contexts.find(host_.get()); | |
383 if (it != all_contexts.end()) { | |
384 share_group = it->second->GetImplementation()->share_group(); | |
385 DCHECK(share_group); | |
386 } | |
387 } | |
388 | 415 |
389 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); | 416 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); |
390 bool free_command_buffer_when_invisible = | 417 bool free_command_buffer_when_invisible = |
391 command_line.HasSwitch(switches::kEnablePruneGpuCommandBuffers); | 418 command_line.HasSwitch(switches::kEnablePruneGpuCommandBuffers); |
392 | 419 |
393 // Create the object exposing the OpenGL API. | 420 // Create the object exposing the OpenGL API. |
394 real_gl_.reset(new gpu::gles2::GLES2Implementation( | 421 real_gl_.reset(new gpu::gles2::GLES2Implementation( |
395 gles2_helper_.get(), | 422 gles2_helper_.get(), |
396 share_group, | 423 gles2_share_group, |
397 transfer_buffer_.get(), | 424 transfer_buffer_.get(), |
398 bind_generates_resources_, | 425 bind_generates_resources_, |
399 free_command_buffer_when_invisible, | 426 free_command_buffer_when_invisible, |
400 command_buffer_.get())); | 427 command_buffer_.get())); |
401 gl_ = real_gl_.get(); | 428 gl_ = real_gl_.get(); |
402 | 429 |
403 if (attributes_.shareResources) { | |
404 // Don't add ourselves to the list before others can get to our ShareGroup. | |
405 g_all_shared_contexts.Get().insert(std::make_pair(host_.get(), this)); | |
406 lock.reset(); | |
407 } | |
408 | |
409 if (!real_gl_->Initialize( | 430 if (!real_gl_->Initialize( |
410 mem_limits_.start_transfer_buffer_size, | 431 mem_limits_.start_transfer_buffer_size, |
411 mem_limits_.min_transfer_buffer_size, | 432 mem_limits_.min_transfer_buffer_size, |
412 mem_limits_.max_transfer_buffer_size, | 433 mem_limits_.max_transfer_buffer_size, |
413 mem_limits_.mapped_memory_reclaim_limit)) { | 434 mem_limits_.mapped_memory_reclaim_limit)) { |
414 return false; | 435 return false; |
415 } | 436 } |
416 | 437 |
| 438 if (add_to_share_group) |
| 439 share_group_->AddContextLocked(this); |
| 440 |
417 if (CommandLine::ForCurrentProcess()->HasSwitch( | 441 if (CommandLine::ForCurrentProcess()->HasSwitch( |
418 switches::kEnableGpuClientTracing)) { | 442 switches::kEnableGpuClientTracing)) { |
419 trace_gl_.reset(new gpu::gles2::GLES2TraceImplementation(gl_)); | 443 trace_gl_.reset(new gpu::gles2::GLES2TraceImplementation(gl_)); |
420 gl_ = trace_gl_.get(); | 444 gl_ = trace_gl_.get(); |
421 } | 445 } |
422 | 446 |
423 return true; | 447 return true; |
424 } | 448 } |
425 | 449 |
426 bool WebGraphicsContext3DCommandBufferImpl::makeContextCurrent() { | 450 bool WebGraphicsContext3DCommandBufferImpl::makeContextCurrent() { |
427 if (!MaybeInitializeGL()) | 451 if (!MaybeInitializeGL()) |
428 return false; | 452 return false; |
429 gles2::SetGLContext(gl_); | 453 gles2::SetGLContext(gl_); |
430 if (command_buffer_->GetLastError() != gpu::error::kNoError) | 454 if (command_buffer_->GetLastError() != gpu::error::kNoError) |
431 return false; | 455 return false; |
432 | 456 |
433 return true; | 457 return true; |
434 } | 458 } |
435 | 459 |
436 uint32_t WebGraphicsContext3DCommandBufferImpl::lastFlushID() { | 460 uint32_t WebGraphicsContext3DCommandBufferImpl::lastFlushID() { |
437 return flush_id_; | 461 return flush_id_; |
438 } | 462 } |
439 | 463 |
440 DELEGATE_TO_GL_R(insertSyncPoint, InsertSyncPointCHROMIUM, unsigned int) | 464 DELEGATE_TO_GL_R(insertSyncPoint, InsertSyncPointCHROMIUM, unsigned int) |
441 | 465 |
442 void WebGraphicsContext3DCommandBufferImpl::Destroy() { | 466 void WebGraphicsContext3DCommandBufferImpl::Destroy() { |
443 if (host_.get()) { | 467 share_group_->RemoveContext(this); |
444 base::AutoLock lock(g_all_shared_contexts_lock.Get()); | |
445 ContextMap& all_contexts = g_all_shared_contexts.Get(); | |
446 ContextMap::iterator it = std::find( | |
447 all_contexts.begin(), | |
448 all_contexts.end(), | |
449 std::pair<GpuChannelHost* const, | |
450 WebGraphicsContext3DCommandBufferImpl*>(host_.get(), this)); | |
451 if (it != all_contexts.end()) | |
452 all_contexts.erase(it); | |
453 } | |
454 | 468 |
455 if (gl_) { | 469 if (gl_) { |
456 // First flush the context to ensure that any pending frees of resources | 470 // First flush the context to ensure that any pending frees of resources |
457 // are completed. Otherwise, if this context is part of a share group, | 471 // are completed. Otherwise, if this context is part of a share group, |
458 // those resources might leak. Also, any remaining side effects of commands | 472 // those resources might leak. Also, any remaining side effects of commands |
459 // issued on this context might not be visible to other contexts in the | 473 // issued on this context might not be visible to other contexts in the |
460 // share group. | 474 // share group. |
461 gl_->Flush(); | 475 gl_->Flush(); |
462 gl_ = NULL; | 476 gl_ = NULL; |
463 } | 477 } |
(...skipping 697 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1161 gpu::CommandBuffer::State state = command_buffer_->GetLastState(); | 1175 gpu::CommandBuffer::State state = command_buffer_->GetLastState(); |
1162 return state.error == gpu::error::kLostContext; | 1176 return state.error == gpu::error::kLostContext; |
1163 } | 1177 } |
1164 | 1178 |
1165 // static | 1179 // static |
1166 WebGraphicsContext3DCommandBufferImpl* | 1180 WebGraphicsContext3DCommandBufferImpl* |
1167 WebGraphicsContext3DCommandBufferImpl::CreateOffscreenContext( | 1181 WebGraphicsContext3DCommandBufferImpl::CreateOffscreenContext( |
1168 GpuChannelHost* host, | 1182 GpuChannelHost* host, |
1169 const WebGraphicsContext3D::Attributes& attributes, | 1183 const WebGraphicsContext3D::Attributes& attributes, |
1170 const GURL& active_url, | 1184 const GURL& active_url, |
1171 const SharedMemoryLimits& limits) { | 1185 const SharedMemoryLimits& limits, |
| 1186 WebGraphicsContext3DCommandBufferImpl* share_context) { |
1172 if (!host) | 1187 if (!host) |
1173 return NULL; | 1188 return NULL; |
| 1189 |
| 1190 if (share_context && share_context->IsCommandBufferContextLost()) |
| 1191 return NULL; |
| 1192 |
1174 return new WebGraphicsContext3DCommandBufferImpl(0, | 1193 return new WebGraphicsContext3DCommandBufferImpl(0, |
1175 active_url, | 1194 active_url, |
1176 host, | 1195 host, |
1177 attributes, | 1196 attributes, |
1178 false, | 1197 false, |
1179 limits); | 1198 limits, |
| 1199 share_context); |
1180 } | 1200 } |
1181 | 1201 |
1182 DELEGATE_TO_GL_5(texImageIOSurface2DCHROMIUM, TexImageIOSurface2DCHROMIUM, | 1202 DELEGATE_TO_GL_5(texImageIOSurface2DCHROMIUM, TexImageIOSurface2DCHROMIUM, |
1183 WGC3Denum, WGC3Dint, WGC3Dint, WGC3Duint, WGC3Duint) | 1203 WGC3Denum, WGC3Dint, WGC3Dint, WGC3Duint, WGC3Duint) |
1184 | 1204 |
1185 DELEGATE_TO_GL_5(texStorage2DEXT, TexStorage2DEXT, | 1205 DELEGATE_TO_GL_5(texStorage2DEXT, TexStorage2DEXT, |
1186 WGC3Denum, WGC3Dint, WGC3Duint, WGC3Dint, WGC3Dint) | 1206 WGC3Denum, WGC3Dint, WGC3Duint, WGC3Dint, WGC3Dint) |
1187 | 1207 |
1188 WebGLId WebGraphicsContext3DCommandBufferImpl::createQueryEXT() { | 1208 WebGLId WebGraphicsContext3DCommandBufferImpl::createQueryEXT() { |
1189 GLuint o; | 1209 GLuint o; |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1342 | 1362 |
1343 } // anonymous namespace | 1363 } // anonymous namespace |
1344 | 1364 |
1345 void WebGraphicsContext3DCommandBufferImpl::OnGpuChannelLost() { | 1365 void WebGraphicsContext3DCommandBufferImpl::OnGpuChannelLost() { |
1346 context_lost_reason_ = convertReason( | 1366 context_lost_reason_ = convertReason( |
1347 command_buffer_->GetLastState().context_lost_reason); | 1367 command_buffer_->GetLastState().context_lost_reason); |
1348 if (context_lost_callback_) { | 1368 if (context_lost_callback_) { |
1349 context_lost_callback_->onContextLost(); | 1369 context_lost_callback_->onContextLost(); |
1350 } | 1370 } |
1351 | 1371 |
| 1372 share_group_->RemoveAllContexts(); |
| 1373 |
1352 DCHECK(host_.get()); | 1374 DCHECK(host_.get()); |
1353 { | 1375 { |
1354 base::AutoLock lock(g_all_shared_contexts_lock.Get()); | 1376 base::AutoLock lock(g_default_share_groups_lock.Get()); |
1355 g_all_shared_contexts.Get().erase(host_.get()); | 1377 g_default_share_groups.Get().erase(host_.get()); |
1356 } | 1378 } |
1357 } | 1379 } |
1358 | 1380 |
1359 void WebGraphicsContext3DCommandBufferImpl::OnErrorMessage( | 1381 void WebGraphicsContext3DCommandBufferImpl::OnErrorMessage( |
1360 const std::string& message, int id) { | 1382 const std::string& message, int id) { |
1361 if (error_message_callback_) { | 1383 if (error_message_callback_) { |
1362 blink::WebString str = blink::WebString::fromUTF8(message.c_str()); | 1384 blink::WebString str = blink::WebString::fromUTF8(message.c_str()); |
1363 error_message_callback_->onErrorMessage(str, id); | 1385 error_message_callback_->onErrorMessage(str, id); |
1364 } | 1386 } |
1365 } | 1387 } |
1366 | 1388 |
1367 } // namespace content | 1389 } // namespace content |
OLD | NEW |