// Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CC_TREES_THREADED_CHANNEL_H_ #define CC_TREES_THREADED_CHANNEL_H_ #include "base/macros.h" #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" namespace base { class SingleThreadTaskRunner; } namespace cc { class ChannelImpl; class ChannelMain; class LayerTreeHost; class ProxyImpl; class ProxyMain; // An implementation of ChannelMain and ChannelImpl that sends commands between // ProxyMain and ProxyImpl across thread boundaries. // // LayerTreeHost creates ThreadedChannel and passes the ownership to ProxyMain. // The object life cycle and communication across threads is as follows: // // // Main Thread | Impl Thread // LayerTreeHost->InitializeProxy | // | | // ProxyMain->Start() | // | ThreadedChannel // --------------------------------------------------------------------------- // ChannelMain::SynchronouslyInitializeImpl ---PostTask---> ThreadedChannel:: // InitializeImplOnImpl // | // ProxyImpl::Create // | // ProxyImpl->Initialize() // . // . // ProxyImpl::ScheduledActionBegin // OutputSurfaceCreation // | // ChannelImpl::RequestNewOutputSurface // ---------------------------------------------------------------------------- // | // ProxyMain->RequestNewOutputSurface()<----PostTask-------- // . // . // ProxyMain->Stop() // | // --------------------------------------------------------------------------- // 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 Create( ProxyMain* proxy_main, TaskRunnerProvider* task_runner_provider); ~ThreadedChannel() override; // ChannelMain Implementation void SetThrottleFrameProductionOnImpl(bool throttle) override; void UpdateTopControlsStateOnImpl(TopControlsState constraints, TopControlsState current, bool animate) override; void InitializeOutputSurfaceOnImpl(OutputSurface* output_surface) override; void MainThreadHasStoppedFlingingOnImpl() override; void SetInputThrottledUntilCommitOnImpl(bool is_throttled) override; void SetDeferCommitsOnImpl(bool defer_commits) override; void SetNeedsCommitOnImpl() override; void BeginMainFrameAbortedOnImpl( CommitEarlyOutReason reason, base::TimeTicks main_thread_start_time) override; void SetNeedsRedrawOnImpl(const gfx::Rect& damage_rect) override; void SetVisibleOnImpl(bool visible) override; // Blocking calls to ProxyImpl void FinishAllRenderingOnImpl(CompletionEvent* completion) override; void ReleaseOutputSurfaceOnImpl(CompletionEvent* completion) override; void MainFrameWillHappenOnImplForTesting( CompletionEvent* completion, bool* main_frame_will_happen) override; void StartCommitOnImpl(CompletionEvent* completion, LayerTreeHost* layer_tree_host, base::TimeTicks main_thread_start_time, bool hold_commit_for_activation) override; void SynchronouslyInitializeImpl( LayerTreeHost* layer_tree_host, scoped_ptr external_begin_frame_source) override; void SynchronouslyCloseImpl() override; // ChannelImpl Implementation void DidCompleteSwapBuffers() override; void SetRendererCapabilitiesMainCopy( const RendererCapabilities& capabilities) override; void BeginMainFrameNotExpectedSoon() override; void DidCommitAndDrawFrame() override; void SetAnimationEvents(scoped_ptr events) override; void DidLoseOutputSurface() override; void RequestNewOutputSurface() override; void DidInitializeOutputSurface( bool success, const RendererCapabilities& capabilities) override; void DidCompletePageScaleAnimation() override; void PostFrameTimingEventsOnMain( scoped_ptr composite_events, scoped_ptr main_frame_events) override; void BeginMainFrame( scoped_ptr begin_main_frame_state) override; protected: ThreadedChannel(ProxyMain* proxy_main, TaskRunnerProvider* task_runner_provider); // Virtual for testing. virtual scoped_ptr CreateProxyImpl( ChannelImpl* channel_impl, LayerTreeHost* layer_tree_host, TaskRunnerProvider* task_runner_provider, scoped_ptr 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 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 proxy_main_weak_ptr); ~CompositorThreadOnly(); scoped_ptr 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> 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 proxy_main_weak_ptr; }; // Called on impl thread. void InitializeImplOnImpl( CompletionEvent* completion, LayerTreeHost* layer_tree_host, scoped_ptr 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_; MainThreadOnly& main(); const MainThreadOnly& main() const; CompositorThreadOnly& impl(); const CompositorThreadOnly& impl() const; // Use accessors instead of this variable directly. MainThreadOnly main_thread_only_vars_unsafe_; // Use accessors instead of this variable directly. CompositorThreadOnly compositor_thread_vars_unsafe_; // Used on the main thread to safely queue calls to ProxyImpl to be run on the // impl thread. base::WeakPtr proxy_impl_weak_ptr_; DISALLOW_COPY_AND_ASSIGN(ThreadedChannel); }; } // namespace cc #endif // CC_TREES_THREADED_CHANNEL_H_