summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkhushalsagar <khushalsagar@chromium.org>2015-09-25 15:44:56 -0700
committerCommit bot <commit-bot@chromium.org>2015-09-25 22:45:38 +0000
commit5d6eb98fd5d6acf448c153e89d09dc506f0e4210 (patch)
treeb49508b32117147fc549c340d905699bdd8b1d81
parente1d87813a4acf3fb824660991ac5b7db86ac5e8f (diff)
downloadchromium_src-5d6eb98fd5d6acf448c153e89d09dc506f0e4210.zip
chromium_src-5d6eb98fd5d6acf448c153e89d09dc506f0e4210.tar.gz
chromium_src-5d6eb98fd5d6acf448c153e89d09dc506f0e4210.tar.bz2
Add basic framework for splitting thread proxy.
ProxyMain and ProxyImpl have been temporarily defined as interfaces to have the implementation in ThreadProxy and incrementally move methods to the different classes. MainThreadOnly and BlockedMainThread are the variables owned by ProxyMain and CompositorThreadOnly are the variables owned by ProxyImpl. All access to the data variables and methods for the 2 sides will be routed through the Channel interfaces with ThreadedChannel providing the implementation for the current case where ProxyMain and ProxyImpl are running on separate threads. BUG=527200 CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel Review URL: https://codereview.chromium.org/1357373002 Cr-Commit-Position: refs/heads/master@{#350935}
-rw-r--r--cc/BUILD.gn6
-rw-r--r--cc/cc.gyp6
-rw-r--r--cc/trees/channel_impl.h27
-rw-r--r--cc/trees/channel_main.h33
-rw-r--r--cc/trees/proxy_impl.h34
-rw-r--r--cc/trees/proxy_main.h40
-rw-r--r--cc/trees/thread_proxy.cc40
-rw-r--r--cc/trees/thread_proxy.h31
-rw-r--r--cc/trees/threaded_channel.cc60
-rw-r--r--cc/trees/threaded_channel.h106
10 files changed, 367 insertions, 16 deletions
diff --git a/cc/BUILD.gn b/cc/BUILD.gn
index 408ab16..b25b8dc 100644
--- a/cc/BUILD.gn
+++ b/cc/BUILD.gn
@@ -452,6 +452,8 @@ component("cc") {
"tiles/tiling_set_raster_queue_required.h",
"trees/blocking_task_runner.cc",
"trees/blocking_task_runner.h",
+ "trees/channel_impl.h",
+ "trees/channel_main.h",
"trees/damage_tracker.cc",
"trees/damage_tracker.h",
"trees/draw_property_utils.cc",
@@ -481,6 +483,8 @@ component("cc") {
"trees/property_tree_builder.h",
"trees/proxy.cc",
"trees/proxy.h",
+ "trees/proxy_impl.h",
+ "trees/proxy_main.h",
"trees/scoped_abort_remaining_swap_promises.h",
"trees/single_thread_proxy.cc",
"trees/single_thread_proxy.h",
@@ -488,6 +492,8 @@ component("cc") {
"trees/swap_promise_monitor.h",
"trees/thread_proxy.cc",
"trees/thread_proxy.h",
+ "trees/threaded_channel.cc",
+ "trees/threaded_channel.h",
"trees/tree_synchronizer.cc",
"trees/tree_synchronizer.h",
]
diff --git a/cc/cc.gyp b/cc/cc.gyp
index d78603b..64b3f11 100644
--- a/cc/cc.gyp
+++ b/cc/cc.gyp
@@ -513,6 +513,8 @@
'tiles/tiling_set_raster_queue_required.h',
'trees/blocking_task_runner.cc',
'trees/blocking_task_runner.h',
+ 'trees/channel_impl.h',
+ 'trees/channel_main.h',
'trees/damage_tracker.cc',
'trees/damage_tracker.h',
'trees/draw_property_utils.cc',
@@ -542,11 +544,15 @@
'trees/property_tree_builder.h',
'trees/proxy.cc',
'trees/proxy.h',
+ 'trees/proxy_impl.h'
+ 'trees/proxy_main.h'
'trees/scoped_abort_remaining_swap_promises.h',
'trees/single_thread_proxy.cc',
'trees/single_thread_proxy.h',
'trees/swap_promise_monitor.cc',
'trees/swap_promise_monitor.h',
+ 'trees/threaded_channel.cc',
+ 'trees/threaded_channel.h',
'trees/thread_proxy.cc',
'trees/thread_proxy.h',
'trees/tree_synchronizer.cc',
diff --git a/cc/trees/channel_impl.h b/cc/trees/channel_impl.h
new file mode 100644
index 0000000..dcaf416
--- /dev/null
+++ b/cc/trees/channel_impl.h
@@ -0,0 +1,27 @@
+// 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_CHANNEL_IMPL_H_
+#define CC_TREES_CHANNEL_IMPL_H_
+
+#include "cc/base/cc_export.h"
+
+namespace cc {
+
+// Channel used to send commands to and receive commands from ProxyMain.
+// The ChannelImpl implementation creates and owns ProxyImpl on receiving the
+// InitializeImpl call from ChannelMain.
+// See channel_main.h
+class CC_EXPORT ChannelImpl {
+ public:
+ // Interface for commands sent to ProxyMain
+ virtual void DidCompleteSwapBuffers() = 0;
+
+ protected:
+ virtual ~ChannelImpl() {}
+};
+
+} // namespace cc
+
+#endif // CC_TREES_CHANNEL_IMPL_H_
diff --git a/cc/trees/channel_main.h b/cc/trees/channel_main.h
new file mode 100644
index 0000000..964d1aa
--- /dev/null
+++ b/cc/trees/channel_main.h
@@ -0,0 +1,33 @@
+// 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_CHANNEL_MAIN_H_
+#define CC_TREES_CHANNEL_MAIN_H_
+
+#include "cc/base/cc_export.h"
+
+namespace cc {
+
+// ChannelMain and ChannelImpl provide an abstract communication layer for
+// the main and impl side of the compositor.
+//
+// The communication sequence between the 2 sides is:
+//
+// LayerTreeHost<-->ProxyMain<-->ChannelMain
+// |
+// |
+// ChannelImpl<-->ProxyImpl<-->LayerTreeHostImpl
+
+class CC_EXPORT ChannelMain {
+ public:
+ // Interface for commands sent to the ProxyImpl
+ virtual void SetThrottleFrameProductionOnImpl(bool throttle) = 0;
+ virtual void SetLayerTreeHostClientReadyOnImpl() = 0;
+
+ virtual ~ChannelMain() {}
+};
+
+} // namespace cc
+
+#endif // CC_TREES_CHANNEL_MAIN_H_
diff --git a/cc/trees/proxy_impl.h b/cc/trees/proxy_impl.h
new file mode 100644
index 0000000..3a6c82b
--- /dev/null
+++ b/cc/trees/proxy_impl.h
@@ -0,0 +1,34 @@
+// 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_PROXY_IMPL_H_
+#define CC_TREES_PROXY_IMPL_H_
+
+#include "base/memory/weak_ptr.h"
+#include "cc/base/cc_export.h"
+
+namespace cc {
+
+// TODO(khushalsagar): The impl side of ThreadProxy. It is currently defined as
+// an interface with the implementation provided by ThreadProxy and will be
+// made an independent class.
+// The methods added to this interface should only use the CompositorThreadOnly
+// variables from ThreadProxy.
+// See crbug/527200
+class CC_EXPORT ProxyImpl {
+ public:
+ // Callback for impl side commands received from the channel.
+ virtual void SetThrottleFrameProductionOnImpl(bool throttle) = 0;
+ virtual void SetLayerTreeHostClientReadyOnImpl() = 0;
+
+ // TODO(khushalsagar): Rename as GetWeakPtr() once ThreadProxy is split.
+ virtual base::WeakPtr<ProxyImpl> GetImplWeakPtr() = 0;
+
+ protected:
+ virtual ~ProxyImpl() {}
+};
+
+} // namespace cc
+
+#endif // CC_TREES_PROXY_IMPL_H_
diff --git a/cc/trees/proxy_main.h b/cc/trees/proxy_main.h
new file mode 100644
index 0000000..71230b4
--- /dev/null
+++ b/cc/trees/proxy_main.h
@@ -0,0 +1,40 @@
+// 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_PROXY_MAIN_H_
+#define CC_TREES_PROXY_MAIN_H_
+
+#include "base/memory/weak_ptr.h"
+#include "cc/base/cc_export.h"
+
+namespace cc {
+class ThreadedChannel;
+
+// TODO(khushalsagar): The main side of ThreadProxy. It is currently defined as
+// an interface with the implementation provided by ThreadProxy and will be
+// made an independent class.
+// The methods added to this interface should only use the MainThreadOnly or
+// BlockedMainThread variables from ThreadProxy.
+// See crbug/527200.
+class CC_EXPORT ProxyMain {
+ public:
+ // TODO(khushalsagar): Make this ChannelMain*. When ProxyMain and
+ // ProxyImpl are split, ProxyImpl will be passed a reference to ChannelImpl
+ // at creation. Right now we just set it directly from ThreadedChannel
+ // when the impl side is initialized.
+ virtual void SetChannel(scoped_ptr<ThreadedChannel> threaded_channel) = 0;
+
+ // Callback for main side commands received from the Channel.
+ virtual void DidCompleteSwapBuffers() = 0;
+
+ // TODO(khushalsagar): Rename as GetWeakPtr() once ThreadProxy is split.
+ virtual base::WeakPtr<ProxyMain> GetMainWeakPtr() = 0;
+
+ protected:
+ virtual ~ProxyMain() {}
+};
+
+} // namespace cc
+
+#endif // CC_TREES_PROXY_MAIN_H_
diff --git a/cc/trees/thread_proxy.cc b/cc/trees/thread_proxy.cc
index 585cbf5..ca6eb73 100644
--- a/cc/trees/thread_proxy.cc
+++ b/cc/trees/thread_proxy.cc
@@ -71,6 +71,10 @@ ThreadProxy::ThreadProxy(
TRACE_EVENT0("cc", "ThreadProxy::ThreadProxy");
DCHECK(IsMainThread());
DCHECK(this->layer_tree_host());
+ // TODO(khushalsagar): Move this to LayerTreeHost#InitializeThreaded once
+ // ThreadProxy is split. LayerTreeHost creates the channel and passes it to
+ // ProxyMain#SetChannel.
+ SetChannel(ThreadedChannel::Create(this, main_task_runner, impl_task_runner));
}
ThreadProxy::MainThreadOnly::MainThreadOnly(ThreadProxy* proxy,
@@ -123,6 +127,11 @@ ThreadProxy::~ThreadProxy() {
DCHECK(!main().started);
}
+void ThreadProxy::SetChannel(scoped_ptr<ThreadedChannel> threaded_channel) {
+ threaded_channel_ = threaded_channel.Pass();
+ main().channel_main = threaded_channel_.get();
+}
+
void ThreadProxy::FinishAllRendering() {
DCHECK(Proxy::IsMainThread());
DCHECK(!main().defer_commits);
@@ -151,13 +160,10 @@ bool ThreadProxy::CommitToActiveTree() const {
void ThreadProxy::SetLayerTreeHostClientReady() {
TRACE_EVENT0("cc", "ThreadProxy::SetLayerTreeHostClientReady");
- Proxy::ImplThreadTaskRunner()->PostTask(
- FROM_HERE,
- base::Bind(&ThreadProxy::SetLayerTreeHostClientReadyOnImplThread,
- impl_thread_weak_ptr_));
+ main().channel_main->SetLayerTreeHostClientReadyOnImpl();
}
-void ThreadProxy::SetLayerTreeHostClientReadyOnImplThread() {
+void ThreadProxy::SetLayerTreeHostClientReadyOnImpl() {
TRACE_EVENT0("cc", "ThreadProxy::SetLayerTreeHostClientReadyOnImplThread");
impl().scheduler->SetCanStart();
}
@@ -187,13 +193,10 @@ void ThreadProxy::SetVisibleOnImplThread(CompletionEvent* completion,
void ThreadProxy::SetThrottleFrameProduction(bool throttle) {
TRACE_EVENT1("cc", "ThreadProxy::SetThrottleFrameProduction", "throttle",
throttle);
- Proxy::ImplThreadTaskRunner()->PostTask(
- FROM_HERE,
- base::Bind(&ThreadProxy::SetThrottleFrameProductionOnImplThread,
- impl_thread_weak_ptr_, throttle));
+ main().channel_main->SetThrottleFrameProductionOnImpl(throttle);
}
-void ThreadProxy::SetThrottleFrameProductionOnImplThread(bool throttle) {
+void ThreadProxy::SetThrottleFrameProductionOnImpl(bool throttle) {
TRACE_EVENT1("cc", "ThreadProxy::SetThrottleFrameProductionOnImplThread",
"throttle", throttle);
impl().scheduler->SetThrottleFrameProduction(throttle);
@@ -355,9 +358,7 @@ void ThreadProxy::DidSwapBuffersCompleteOnImplThread() {
"ThreadProxy::DidSwapBuffersCompleteOnImplThread");
DCHECK(IsImplThread());
impl().scheduler->DidSwapBuffersComplete();
- Proxy::MainThreadTaskRunner()->PostTask(
- FROM_HERE,
- base::Bind(&ThreadProxy::DidCompleteSwapBuffers, main_thread_weak_ptr_));
+ impl().channel_impl->DidCompleteSwapBuffers();
}
void ThreadProxy::WillBeginImplFrame(const BeginFrameArgs& args) {
@@ -1016,6 +1017,11 @@ void ThreadProxy::SetAnimationEvents(scoped_ptr<AnimationEventsVector> events) {
void ThreadProxy::InitializeImplOnImplThread(CompletionEvent* completion) {
TRACE_EVENT0("cc", "ThreadProxy::InitializeImplOnImplThread");
DCHECK(IsImplThread());
+
+ // TODO(khushalsagar): ThreadedChannel will create ProxyImpl here and pass a
+ // reference to itself.
+ impl().channel_impl = threaded_channel_.get();
+
impl().layer_tree_host_impl =
layer_tree_host()->CreateLayerTreeHostImpl(this);
@@ -1249,4 +1255,12 @@ void ThreadProxy::PostFrameTimingEvents(
main_frame_events.Pass());
}
+base::WeakPtr<ProxyMain> ThreadProxy::GetMainWeakPtr() {
+ return main_thread_weak_ptr_;
+}
+
+base::WeakPtr<ProxyImpl> ThreadProxy::GetImplWeakPtr() {
+ return impl_thread_weak_ptr_;
+}
+
} // namespace cc
diff --git a/cc/trees/thread_proxy.h b/cc/trees/thread_proxy.h
index 9abca17..a6b3cf7 100644
--- a/cc/trees/thread_proxy.h
+++ b/cc/trees/thread_proxy.h
@@ -17,6 +17,7 @@
#include "cc/scheduler/scheduler.h"
#include "cc/trees/layer_tree_host_impl.h"
#include "cc/trees/proxy.h"
+#include "cc/trees/threaded_channel.h"
namespace base {
class SingleThreadTaskRunner;
@@ -25,13 +26,20 @@ class SingleThreadTaskRunner;
namespace cc {
class BeginFrameSource;
+class ChannelImpl;
+class ChannelMain;
class ContextProvider;
class InputHandlerClient;
class LayerTreeHost;
+class ProxyImpl;
+class ProxyMain;
class Scheduler;
class ScopedThreadProxy;
+class ThreadedChannel;
class CC_EXPORT ThreadProxy : public Proxy,
+ public ProxyMain,
+ public ProxyImpl,
NON_EXPORTED_BASE(LayerTreeHostImplClient),
NON_EXPORTED_BASE(SchedulerClient) {
public:
@@ -86,6 +94,10 @@ class CC_EXPORT ThreadProxy : public Proxy,
RendererCapabilities renderer_capabilities_main_thread_copy;
+ // TODO(khushalsagar): Make this scoped_ptr<ChannelMain> when ProxyMain
+ // and ProxyImpl are split.
+ ChannelMain* channel_main;
+
base::WeakPtrFactory<ThreadProxy> weak_factory;
};
@@ -144,6 +156,9 @@ class CC_EXPORT ThreadProxy : public Proxy,
BeginFrameArgs last_processed_begin_main_frame_args;
scoped_ptr<LayerTreeHostImpl> layer_tree_host_impl;
+
+ ChannelImpl* channel_impl;
+
base::WeakPtrFactory<ThreadProxy> weak_factory;
};
@@ -231,6 +246,16 @@ class CC_EXPORT ThreadProxy : public Proxy,
void SendBeginFramesToChildren(const BeginFrameArgs& args) override;
void SendBeginMainFrameNotExpectedSoon() override;
+ // ProxyMain implementation
+ base::WeakPtr<ProxyMain> GetMainWeakPtr() override;
+ void SetChannel(scoped_ptr<ThreadedChannel> threaded_channel) override;
+ void DidCompleteSwapBuffers() override;
+
+ // ProxyImpl implementation
+ base::WeakPtr<ProxyImpl> GetImplWeakPtr() override;
+ void SetThrottleFrameProductionOnImpl(bool throttle) override;
+ void SetLayerTreeHostClientReadyOnImpl() override;
+
protected:
ThreadProxy(
LayerTreeHost* layer_tree_host,
@@ -246,7 +271,6 @@ class CC_EXPORT ThreadProxy : public Proxy,
scoped_ptr<BeginMainFrameAndCommitState> begin_main_frame_state);
void BeginMainFrameNotExpectedSoon();
void DidCommitAndDrawFrame();
- void DidCompleteSwapBuffers();
void SetAnimationEvents(scoped_ptr<AnimationEventsVector> queue);
void DidLoseOutputSurface();
void RequestNewOutputSurface();
@@ -265,9 +289,7 @@ class CC_EXPORT ThreadProxy : public Proxy,
void BeginMainFrameAbortedOnImplThread(CommitEarlyOutReason reason);
void FinishAllRenderingOnImplThread(CompletionEvent* completion);
void InitializeImplOnImplThread(CompletionEvent* completion);
- void SetLayerTreeHostClientReadyOnImplThread();
void SetVisibleOnImplThread(CompletionEvent* completion, bool visible);
- void SetThrottleFrameProductionOnImplThread(bool throttle);
void HasInitializedOutputSurfaceOnImplThread(
CompletionEvent* completion,
bool* has_initialized_output_surface);
@@ -302,6 +324,9 @@ class CC_EXPORT ThreadProxy : public Proxy,
CompositorThreadOnly compositor_thread_vars_unsafe_;
CompositorThreadOnly& impl();
+ // TODO(khushalsagar): Remove this. Temporary variable to hold the channel.
+ scoped_ptr<ThreadedChannel> threaded_channel_;
+
base::WeakPtr<ThreadProxy> main_thread_weak_ptr_;
base::WeakPtr<ThreadProxy> impl_thread_weak_ptr_;
diff --git a/cc/trees/threaded_channel.cc b/cc/trees/threaded_channel.cc
new file mode 100644
index 0000000..3bc44c9
--- /dev/null
+++ b/cc/trees/threaded_channel.cc
@@ -0,0 +1,60 @@
+// 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.
+
+#include "cc/trees/threaded_channel.h"
+
+#include "base/bind.h"
+#include "base/single_thread_task_runner.h"
+#include "base/trace_event/trace_event.h"
+
+namespace cc {
+
+scoped_ptr<ThreadedChannel> ThreadedChannel::Create(
+ ThreadProxy* thread_proxy,
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner) {
+ return make_scoped_ptr(
+ new ThreadedChannel(thread_proxy, main_task_runner, impl_task_runner));
+}
+
+ThreadedChannel::ThreadedChannel(
+ ThreadProxy* thread_proxy,
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner)
+ : proxy_main_(thread_proxy),
+ proxy_impl_(thread_proxy),
+ main_task_runner_(main_task_runner),
+ impl_task_runner_(impl_task_runner) {}
+
+void ThreadedChannel::SetThrottleFrameProductionOnImpl(bool throttle) {
+ ImplThreadTaskRunner()->PostTask(
+ FROM_HERE, base::Bind(&ProxyImpl::SetThrottleFrameProductionOnImpl,
+ proxy_impl_->GetImplWeakPtr(), throttle));
+}
+
+void ThreadedChannel::SetLayerTreeHostClientReadyOnImpl() {
+ ImplThreadTaskRunner()->PostTask(
+ FROM_HERE, base::Bind(&ProxyImpl::SetLayerTreeHostClientReadyOnImpl,
+ proxy_impl_->GetImplWeakPtr()));
+}
+
+void ThreadedChannel::DidCompleteSwapBuffers() {
+ MainThreadTaskRunner()->PostTask(
+ FROM_HERE, base::Bind(&ProxyMain::DidCompleteSwapBuffers,
+ proxy_main_->GetMainWeakPtr()));
+}
+
+ThreadedChannel::~ThreadedChannel() {
+ TRACE_EVENT0("cc", "ThreadChannel::~ThreadChannel");
+}
+
+base::SingleThreadTaskRunner* ThreadedChannel::MainThreadTaskRunner() const {
+ return main_task_runner_.get();
+}
+
+base::SingleThreadTaskRunner* ThreadedChannel::ImplThreadTaskRunner() const {
+ return impl_task_runner_.get();
+}
+
+} // namespace cc
diff --git a/cc/trees/threaded_channel.h b/cc/trees/threaded_channel.h
new file mode 100644
index 0000000..70238f3
--- /dev/null
+++ b/cc/trees/threaded_channel.h
@@ -0,0 +1,106 @@
+// 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/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "cc/base/cc_export.h"
+#include "cc/trees/channel_impl.h"
+#include "cc/trees/channel_main.h"
+#include "cc/trees/proxy_impl.h"
+#include "cc/trees/proxy_main.h"
+#include "cc/trees/thread_proxy.h"
+
+namespace base {
+class SingleThreadTaskRunner;
+}
+
+namespace cc {
+class ChannelImpl;
+class ChannelMain;
+class ProxyImpl;
+class ProxyMain;
+class ThreadProxy;
+
+// 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::InitializeImpl ---PostTask---> ThreadedChannel::
+// InitializeImplOnImplThread
+// |
+// ProxyImpl::Create
+// |
+// ProxyImpl->Initialize()
+// .
+// .
+// ProxyImpl::ScheduledActionBegin
+// OutputSurfaceCreation
+// |
+// ChannelImpl::RequestNewOutputSurface
+// ----------------------------------------------------------------------------
+// |
+// ProxyMain->RequestNewOutputSurface()<----PostTask--------
+// .
+// .
+// ProxyMain->LayerTreeHostClosed
+// |
+// ---------------------------------------------------------------------------
+// ChannelMain::SetLayerTreeClosedOnImpl---PostTask---> ProxyImpl->
+// SetLayerTreeClosed
+// ----------------------------------------------------------------------------
+
+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,
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner);
+
+ ~ThreadedChannel() override;
+
+ // ChannelMain Implementation
+ void SetThrottleFrameProductionOnImpl(bool throttle) override;
+ void SetLayerTreeHostClientReadyOnImpl() override;
+
+ // ChannelImpl Implementation
+ void DidCompleteSwapBuffers() override;
+
+ protected:
+ ThreadedChannel(ThreadProxy* thread_proxy,
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner);
+
+ private:
+ base::SingleThreadTaskRunner* MainThreadTaskRunner() const;
+ base::SingleThreadTaskRunner* ImplThreadTaskRunner() const;
+
+ ProxyMain* proxy_main_;
+
+ ProxyImpl* proxy_impl_;
+
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
+
+ scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner_;
+
+ DISALLOW_COPY_AND_ASSIGN(ThreadedChannel);
+};
+
+} // namespace cc
+
+#endif // CC_TREES_THREADED_CHANNEL_H_