Index: cc/trees/threaded_channel.h |
diff --git a/cc/trees/threaded_channel.h b/cc/trees/threaded_channel.h |
index ca7fc04c0a7319f5aa6ce7bfe0bc2ca4b0c102e1..5d10f4af5cdbfbd95ec824895fecc1f38a725e70 100644 |
--- a/cc/trees/threaded_channel.h |
+++ b/cc/trees/threaded_channel.h |
@@ -7,13 +7,13 @@ |
#include "base/memory/ref_counted.h" |
#include "base/memory/scoped_ptr.h" |
+#include "base/memory/weak_ptr.h" |
#include "cc/base/cc_export.h" |
#include "cc/trees/channel_impl.h" |
#include "cc/trees/channel_main.h" |
#include "cc/trees/proxy_common.h" |
#include "cc/trees/proxy_impl.h" |
#include "cc/trees/proxy_main.h" |
-#include "cc/trees/thread_proxy.h" |
namespace base { |
class SingleThreadTaskRunner; |
@@ -22,9 +22,9 @@ class SingleThreadTaskRunner; |
namespace cc { |
class ChannelImpl; |
class ChannelMain; |
+class LayerTreeHost; |
class ProxyImpl; |
class ProxyMain; |
-class ThreadProxy; |
// An implementation of ChannelMain and ChannelImpl that sends commands between |
// ProxyMain and ProxyImpl across thread boundaries. |
@@ -39,8 +39,8 @@ class ThreadProxy; |
// ProxyMain->Start() | |
// | ThreadedChannel |
// --------------------------------------------------------------------------- |
-// ChannelMain::InitializeImpl ---PostTask---> ThreadedChannel:: |
-// InitializeImplOnImplThread |
+// ChannelMain::SynchronouslyInitializeImpl ---PostTask---> ThreadedChannel:: |
+// InitializeImplOnImpl |
// | |
// ProxyImpl::Create |
// | |
@@ -56,20 +56,27 @@ class ThreadProxy; |
// ProxyMain->RequestNewOutputSurface()<----PostTask-------- |
// . |
// . |
-// ProxyMain->LayerTreeHostClosed |
+// ProxyMain->Stop() |
// | |
// --------------------------------------------------------------------------- |
-// ChannelMain::SetLayerTreeClosedOnImpl---PostTask---> ProxyImpl-> |
-// SetLayerTreeClosed |
+// ChannelMain::SynchronouslyCloseImpl ---PostTask---> ThreadedChannel:: |
+// CloseImplOnImpl |
// ---------------------------------------------------------------------------- |
+// |
+// ThreadedChannel is created and destroyed on the main thread but can be |
+// called from main or impl thread. It is safe for the Threadedchannel to be |
+// called on the impl thread because: |
+// 1) The only impl-threaded callers of ThreadedChannel are the ThreadedChannel |
+// itself and ProxyImpl which is created and owned by the ThreadedChannel. |
+// 2) ThreadedChannel blocks the main thread in |
+// ThreadedChannel::SynchronouslyCloseImpl to wait for the impl-thread teardown |
+// to complete, so there is no risk of any queued tasks calling it on the impl |
+// thread after it has been deleted on the main thread. |
class CC_EXPORT ThreadedChannel : public ChannelMain, public ChannelImpl { |
public: |
static scoped_ptr<ThreadedChannel> Create( |
- // TODO(khushalsagar): Make this ProxyMain* and write the initialization |
- // sequence. Currently ThreadProxy implements both so we pass the pointer |
- // and set ProxyImpl. |
- ThreadProxy* thread_proxy, |
+ ProxyMain* proxy_main, |
TaskRunnerProvider* task_runner_provider); |
~ThreadedChannel() override; |
@@ -93,7 +100,6 @@ class CC_EXPORT ThreadedChannel : public ChannelMain, public ChannelImpl { |
// Blocking calls to ProxyImpl |
void FinishAllRenderingOnImpl(CompletionEvent* completion) override; |
void ReleaseOutputSurfaceOnImpl(CompletionEvent* completion) override; |
- void FinishGLOnImpl(CompletionEvent* completion) override; |
void MainFrameWillHappenOnImplForTesting( |
CompletionEvent* completion, |
bool* main_frame_will_happen) override; |
@@ -101,9 +107,10 @@ class CC_EXPORT ThreadedChannel : public ChannelMain, public ChannelImpl { |
LayerTreeHost* layer_tree_host, |
base::TimeTicks main_thread_start_time, |
bool hold_commit_for_activation) override; |
- void InitializeImplOnImpl(CompletionEvent* completion, |
- LayerTreeHost* layer_tree_host) override; |
- void LayerTreeHostClosedOnImpl(CompletionEvent* completion) override; |
+ void SynchronouslyInitializeImpl( |
+ LayerTreeHost* layer_tree_host, |
+ scoped_ptr<BeginFrameSource> external_begin_frame_source) override; |
+ void SynchronouslyCloseImpl() override; |
// ChannelImpl Implementation |
void DidCompleteSwapBuffers() override; |
@@ -125,23 +132,84 @@ class CC_EXPORT ThreadedChannel : public ChannelMain, public ChannelImpl { |
void BeginMainFrame( |
scoped_ptr<BeginMainFrameAndCommitState> begin_main_frame_state) override; |
+ // Should be called on impl thread only. |
+ ProxyImpl* GetProxyImplForTesting() const; |
+ |
protected: |
- ThreadedChannel(ThreadProxy* thread_proxy, |
+ ThreadedChannel(ProxyMain* proxy_main, |
TaskRunnerProvider* task_runner_provider); |
+ // Virtual for testing. |
+ virtual scoped_ptr<ProxyImpl> CreateProxyImpl( |
+ ChannelImpl* channel_impl, |
+ LayerTreeHost* layer_tree_host, |
+ TaskRunnerProvider* task_runner_provider, |
+ scoped_ptr<BeginFrameSource> external_begin_frame_source); |
+ |
private: |
+ // The members of this struct should be accessed on the main thread only. |
+ struct MainThreadOnly { |
+ explicit MainThreadOnly(ProxyMain* proxy_main); |
+ ~MainThreadOnly(); |
+ |
+ base::WeakPtrFactory<ProxyMain> proxy_main_weak_factory; |
+ bool initialized; |
+ }; |
+ |
+ // The members of this struct should be accessed on the impl thread only. |
+ struct CompositorThreadOnly { |
+ explicit CompositorThreadOnly(base::WeakPtr<ProxyMain> proxy_main_weak_ptr); |
+ ~CompositorThreadOnly(); |
+ |
+ scoped_ptr<ProxyImpl> proxy_impl; |
+ |
+ // We use a scoped_ptr for the weak ptr factory here since the factory is |
+ // created after ProxyImpl is created in InitializeImplOnImpl. Since the |
+ // weak ptrs are needed only by the ThreadedChannel to safely post tasks on |
+ // ProxyImpl to be run on the impl thread, we avoid creating it in ProxyImpl |
+ // and ensure that it is destroyed before ProxyImpl during the impl-thread |
+ // tear down in CloseImplOnImpl. |
+ scoped_ptr<base::WeakPtrFactory<ProxyImpl>> proxy_impl_weak_factory; |
+ |
+ // Used on the impl thread to queue calls to ProxyMain to be run on the main |
+ // thread. Since the weak pointer is invalidated after the impl-thread tear |
+ // down in SynchronouslyCloseImpl, this ensures that any tasks posted to |
+ // ProxyMain from the impl thread are abandoned after the impl side has been |
+ // destroyed. |
+ base::WeakPtr<ProxyMain> proxy_main_weak_ptr; |
+ }; |
+ |
+ // Called on impl thread. |
+ void InitializeImplOnImpl( |
+ CompletionEvent* completion, |
+ LayerTreeHost* layer_tree_host, |
+ scoped_ptr<BeginFrameSource> external_begin_frame_source); |
+ void CloseImplOnImpl(CompletionEvent* completion); |
+ |
+ bool IsInitialized() const; |
+ |
base::SingleThreadTaskRunner* MainThreadTaskRunner() const; |
base::SingleThreadTaskRunner* ImplThreadTaskRunner() const; |
+ bool IsMainThread() const; |
+ bool IsImplThread() const; |
+ |
+ TaskRunnerProvider* task_runner_provider_; |
- ProxyMain* proxy_main_; |
+ MainThreadOnly& main(); |
+ const MainThreadOnly& main() const; |
- ProxyImpl* proxy_impl_; |
+ CompositorThreadOnly& impl(); |
+ const CompositorThreadOnly& impl() const; |
- TaskRunnerProvider* task_runner_provider_; |
+ // Use accessors instead of this variable directly. |
+ MainThreadOnly main_thread_only_vars_unsafe_; |
- scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; |
+ // Use accessors instead of this variable directly. |
+ CompositorThreadOnly compositor_thread_vars_unsafe_; |
- scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner_; |
+ // Used on the main thread to safely queue calls to ProxyImpl to be run on the |
+ // impl thread. |
+ base::WeakPtr<ProxyImpl> proxy_impl_weak_ptr_; |
DISALLOW_COPY_AND_ASSIGN(ThreadedChannel); |
}; |