diff options
Diffstat (limited to 'cc/trees/threaded_channel.h')
-rw-r--r-- | cc/trees/threaded_channel.h | 110 |
1 files changed, 89 insertions, 21 deletions
diff --git a/cc/trees/threaded_channel.h b/cc/trees/threaded_channel.h index ca7fc04..5d10f4a 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); }; |