OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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/browser/aura/gpu_process_transport_factory.h" | 5 #include "content/browser/aura/gpu_process_transport_factory.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 return texture_id_; | 67 return texture_id_; |
68 } | 68 } |
69 | 69 |
70 virtual WebKit::WebGraphicsContext3D* HostContext3D() OVERRIDE { | 70 virtual WebKit::WebGraphicsContext3D* HostContext3D() OVERRIDE { |
71 return host_context_; | 71 return host_context_; |
72 } | 72 } |
73 | 73 |
74 // ImageTransportFactory overrides: | 74 // ImageTransportFactory overrides: |
75 virtual void OnLostResources() OVERRIDE { | 75 virtual void OnLostResources() OVERRIDE { |
76 DeleteTexture(); | 76 DeleteTexture(); |
| 77 host_context_ = NULL; |
77 } | 78 } |
78 | 79 |
79 protected: | 80 protected: |
80 virtual ~OwnedTexture() { | 81 virtual ~OwnedTexture() { |
81 ImageTransportFactory::GetInstance()->RemoveObserver(this); | 82 ImageTransportFactory::GetInstance()->RemoveObserver(this); |
82 DeleteTexture(); | 83 DeleteTexture(); |
83 } | 84 } |
84 | 85 |
85 protected: | 86 protected: |
86 void DeleteTexture() { | 87 void DeleteTexture() { |
87 if (texture_id_) { | 88 if (texture_id_) { |
88 host_context_->deleteTexture(texture_id_); | 89 host_context_->deleteTexture(texture_id_); |
89 texture_id_ = 0; | 90 texture_id_ = 0; |
90 } | 91 } |
91 } | 92 } |
92 | 93 |
93 // A raw pointer. This |ImageTransportClientTexture| will be destroyed | 94 // The OnLostResources() callback will happen before this context |
94 // before the |host_context_| via | 95 // pointer is destroyed. |
95 // |ImageTransportFactoryObserver::OnLostContext()| handlers. | |
96 WebKit::WebGraphicsContext3D* host_context_; | 96 WebKit::WebGraphicsContext3D* host_context_; |
97 unsigned texture_id_; | 97 unsigned texture_id_; |
98 | 98 |
99 DISALLOW_COPY_AND_ASSIGN(OwnedTexture); | 99 DISALLOW_COPY_AND_ASSIGN(OwnedTexture); |
100 }; | 100 }; |
101 | 101 |
102 class ImageTransportClientTexture : public OwnedTexture { | 102 class ImageTransportClientTexture : public OwnedTexture { |
103 public: | 103 public: |
104 ImageTransportClientTexture( | 104 ImageTransportClientTexture( |
105 WebKit::WebGraphicsContext3D* host_context, | 105 WebKit::WebGraphicsContext3D* host_context, |
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
380 observer_list_.AddObserver(observer); | 380 observer_list_.AddObserver(observer); |
381 } | 381 } |
382 | 382 |
383 void GpuProcessTransportFactory::RemoveObserver( | 383 void GpuProcessTransportFactory::RemoveObserver( |
384 ImageTransportFactoryObserver* observer) { | 384 ImageTransportFactoryObserver* observer) { |
385 observer_list_.RemoveObserver(observer); | 385 observer_list_.RemoveObserver(observer); |
386 } | 386 } |
387 | 387 |
388 scoped_refptr<cc::ContextProvider> | 388 scoped_refptr<cc::ContextProvider> |
389 GpuProcessTransportFactory::OffscreenContextProviderForMainThread() { | 389 GpuProcessTransportFactory::OffscreenContextProviderForMainThread() { |
390 if (!shared_contexts_main_thread_.get() || | 390 // Don't check for DestroyedOnMainThread() here. We hear about context |
391 shared_contexts_main_thread_->DestroyedOnMainThread()) { | 391 // loss for this context through the lost context callback. If the context |
| 392 // is lost, we want to leave this ContextProvider available until the lost |
| 393 // context notification is sent to the ImageTransportFactoryObserver clients. |
| 394 if (!shared_contexts_main_thread_.get()) { |
392 shared_contexts_main_thread_ = ContextProviderCommandBuffer::Create( | 395 shared_contexts_main_thread_ = ContextProviderCommandBuffer::Create( |
393 GpuProcessTransportFactory::CreateOffscreenCommandBufferContext()); | 396 GpuProcessTransportFactory::CreateOffscreenCommandBufferContext()); |
394 if (shared_contexts_main_thread_) { | 397 if (shared_contexts_main_thread_) { |
395 shared_contexts_main_thread_->SetLostContextCallback(base::Bind( | 398 shared_contexts_main_thread_->SetLostContextCallback(base::Bind( |
396 &GpuProcessTransportFactory:: | 399 &GpuProcessTransportFactory:: |
397 OnLostMainThreadSharedContextInsideCallback, | 400 OnLostMainThreadSharedContextInsideCallback, |
398 callback_factory_.GetWeakPtr())); | 401 callback_factory_.GetWeakPtr())); |
399 | 402 |
400 if (!shared_contexts_main_thread_->BindToCurrentThread()) | 403 if (!shared_contexts_main_thread_->BindToCurrentThread()) |
401 shared_contexts_main_thread_ = NULL; | 404 shared_contexts_main_thread_ = NULL; |
402 } | 405 } |
403 } | 406 } |
404 return shared_contexts_main_thread_; | 407 return shared_contexts_main_thread_; |
405 } | 408 } |
406 | 409 |
407 scoped_refptr<cc::ContextProvider> | 410 scoped_refptr<cc::ContextProvider> |
408 GpuProcessTransportFactory::OffscreenContextProviderForCompositorThread() { | 411 GpuProcessTransportFactory::OffscreenContextProviderForCompositorThread() { |
409 if (!shared_contexts_compositor_thread_.get() || | 412 // The lifetime of this context is tied to the main thread context so that |
410 shared_contexts_compositor_thread_->DestroyedOnMainThread()) { | 413 // they are always in the same share group. So do not check for |
| 414 // DestroyedOnMainThread(). |
| 415 if (!shared_contexts_compositor_thread_.get()) { |
411 shared_contexts_compositor_thread_ = ContextProviderCommandBuffer::Create( | 416 shared_contexts_compositor_thread_ = ContextProviderCommandBuffer::Create( |
412 GpuProcessTransportFactory::CreateOffscreenCommandBufferContext()); | 417 GpuProcessTransportFactory::CreateOffscreenCommandBufferContext()); |
413 } | 418 } |
414 return shared_contexts_compositor_thread_; | 419 return shared_contexts_compositor_thread_; |
415 } | 420 } |
416 | 421 |
417 void GpuProcessTransportFactory::OnLostContext(ui::Compositor* compositor) { | 422 void GpuProcessTransportFactory::OnLostContext(ui::Compositor* compositor) { |
418 LOG(ERROR) << "Lost UI compositor context."; | 423 LOG(ERROR) << "Lost UI compositor context."; |
419 PerCompositorData* data = per_compositor_data_[compositor]; | 424 PerCompositorData* data = per_compositor_data_[compositor]; |
420 DCHECK(data); | 425 DCHECK(data); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
486 | 491 |
487 void GpuProcessTransportFactory::OnLostMainThreadSharedContextInsideCallback() { | 492 void GpuProcessTransportFactory::OnLostMainThreadSharedContextInsideCallback() { |
488 base::MessageLoop::current()->PostTask( | 493 base::MessageLoop::current()->PostTask( |
489 FROM_HERE, | 494 FROM_HERE, |
490 base::Bind(&GpuProcessTransportFactory::OnLostMainThreadSharedContext, | 495 base::Bind(&GpuProcessTransportFactory::OnLostMainThreadSharedContext, |
491 callback_factory_.GetWeakPtr())); | 496 callback_factory_.GetWeakPtr())); |
492 } | 497 } |
493 | 498 |
494 void GpuProcessTransportFactory::OnLostMainThreadSharedContext() { | 499 void GpuProcessTransportFactory::OnLostMainThreadSharedContext() { |
495 LOG(ERROR) << "Lost UI shared context."; | 500 LOG(ERROR) << "Lost UI shared context."; |
| 501 |
496 // Keep old resources around while we call the observers, but ensure that | 502 // Keep old resources around while we call the observers, but ensure that |
497 // new resources are created if needed. | 503 // new resources are created if needed. |
| 504 // Kill shared contexts for both threads in tandem so they are always in |
| 505 // the same share group. |
498 | 506 |
499 scoped_refptr<ContextProviderCommandBuffer> old_contexts_main_thread = | 507 scoped_refptr<cc::ContextProvider> lost_shared_contexts_main_thread = |
500 shared_contexts_main_thread_; | 508 shared_contexts_main_thread_; |
| 509 scoped_refptr<cc::ContextProvider> lost_shared_contexts_compositor_thread = |
| 510 shared_contexts_compositor_thread_; |
501 shared_contexts_main_thread_ = NULL; | 511 shared_contexts_main_thread_ = NULL; |
| 512 shared_contexts_compositor_thread_ = NULL; |
502 | 513 |
503 scoped_ptr<GLHelper> old_helper(gl_helper_.release()); | 514 scoped_ptr<GLHelper> lost_gl_helper = gl_helper_.Pass(); |
504 | 515 |
505 FOR_EACH_OBSERVER(ImageTransportFactoryObserver, | 516 FOR_EACH_OBSERVER(ImageTransportFactoryObserver, |
506 observer_list_, | 517 observer_list_, |
507 OnLostResources()); | 518 OnLostResources()); |
| 519 |
| 520 // Kill things that use the shared context before killing the shared context. |
| 521 lost_gl_helper.reset(); |
| 522 lost_shared_contexts_main_thread = NULL; |
| 523 lost_shared_contexts_compositor_thread = NULL; |
508 } | 524 } |
509 | 525 |
510 } // namespace content | 526 } // namespace content |
OLD | NEW |