summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkhushalsagar <khushalsagar@chromium.org>2016-01-29 18:47:17 -0800
committerCommit bot <commit-bot@chromium.org>2016-01-30 02:48:18 +0000
commitb0d8691b17203c4e033ff5ee1a98a9de99a66734 (patch)
tree7f12cbbd1e2e5601de472dd80070243015158afd
parenta5c40ea4cf0e867757dfb4741c9a1ef838b8f82f (diff)
downloadchromium_src-b0d8691b17203c4e033ff5ee1a98a9de99a66734.zip
chromium_src-b0d8691b17203c4e033ff5ee1a98a9de99a66734.tar.gz
chromium_src-b0d8691b17203c4e033ff5ee1a98a9de99a66734.tar.bz2
cc: Route output surface requests and visiblity calls for the remote
client LayerTreeHost. This also fixes the error for commits aborted on the server due to output surface lost. BUG=550687, 577301 CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel Review URL: https://codereview.chromium.org/1583033002 Cr-Commit-Position: refs/heads/master@{#372522}
-rw-r--r--cc/BUILD.gn1
-rw-r--r--cc/cc_tests.gyp1
-rw-r--r--cc/test/layer_tree_test.cc33
-rw-r--r--cc/test/layer_tree_test.h5
-rw-r--r--cc/trees/layer_tree_host.cc7
-rw-r--r--cc/trees/layer_tree_host_unittest_remote_server.cc97
-rw-r--r--cc/trees/remote_channel_impl.cc71
-rw-r--r--cc/trees/remote_channel_impl.h18
-rw-r--r--cc/trees/remote_channel_main.cc9
-rw-r--r--cc/trees/remote_channel_unittest.cc26
10 files changed, 251 insertions, 17 deletions
diff --git a/cc/BUILD.gn b/cc/BUILD.gn
index 5c3d6d56..0a166e0 100644
--- a/cc/BUILD.gn
+++ b/cc/BUILD.gn
@@ -907,6 +907,7 @@ test("cc_unittests") {
"trees/layer_tree_host_unittest_picture.cc",
"trees/layer_tree_host_unittest_proxy.cc",
"trees/layer_tree_host_unittest_record_gpu_histogram.cc",
+ "trees/layer_tree_host_unittest_remote_server.cc",
"trees/layer_tree_host_unittest_scroll.cc",
"trees/layer_tree_host_unittest_serialization.cc",
"trees/layer_tree_host_unittest_video.cc",
diff --git a/cc/cc_tests.gyp b/cc/cc_tests.gyp
index 0ebfa22..986ff53 100644
--- a/cc/cc_tests.gyp
+++ b/cc/cc_tests.gyp
@@ -146,6 +146,7 @@
'trees/layer_tree_host_unittest_picture.cc',
'trees/layer_tree_host_unittest_proxy.cc',
'trees/layer_tree_host_unittest_record_gpu_histogram.cc',
+ 'trees/layer_tree_host_unittest_remote_server.cc',
'trees/layer_tree_host_unittest_scroll.cc',
'trees/layer_tree_host_unittest_serialization.cc',
'trees/layer_tree_host_unittest_video.cc',
diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc
index a5a7a3d..844bd1c 100644
--- a/cc/test/layer_tree_test.cc
+++ b/cc/test/layer_tree_test.cc
@@ -691,8 +691,35 @@ void LayerTreeTest::PostNextCommitWaitsForActivationToMainThread() {
main_thread_weak_ptr_));
}
+void LayerTreeTest::SetOutputSurfaceOnLayerTreeHost(
+ scoped_ptr<OutputSurface> output_surface) {
+ if (IsRemoteTest()) {
+ DCHECK(remote_client_layer_tree_host_);
+ remote_client_layer_tree_host_->SetOutputSurface(std::move(output_surface));
+ } else {
+ layer_tree_host_->SetOutputSurface(std::move(output_surface));
+ }
+}
+
+scoped_ptr<OutputSurface> LayerTreeTest::ReleaseOutputSurfaceOnLayerTreeHost() {
+ if (IsRemoteTest()) {
+ DCHECK(remote_client_layer_tree_host_);
+ return remote_client_layer_tree_host_->ReleaseOutputSurface();
+ }
+ return layer_tree_host_->ReleaseOutputSurface();
+}
+
+void LayerTreeTest::SetVisibleOnLayerTreeHost(bool visible) {
+ layer_tree_host_->SetVisible(visible);
+
+ if (IsRemoteTest()) {
+ DCHECK(remote_client_layer_tree_host_);
+ remote_client_layer_tree_host_->SetVisible(visible);
+ }
+}
+
void LayerTreeTest::WillBeginTest() {
- layer_tree_host_->SetVisible(true);
+ SetVisibleOnLayerTreeHost(true);
}
void LayerTreeTest::DoBeginTest() {
@@ -845,7 +872,7 @@ void LayerTreeTest::DispatchSetNeedsRedrawRect(const gfx::Rect& damage_rect) {
void LayerTreeTest::DispatchSetVisible(bool visible) {
DCHECK(!task_runner_provider() || task_runner_provider()->IsMainThread());
if (layer_tree_host_)
- layer_tree_host_->SetVisible(visible);
+ SetVisibleOnLayerTreeHost(visible);
}
void LayerTreeTest::DispatchSetNextCommitForcesRedraw() {
@@ -917,7 +944,7 @@ void LayerTreeTest::RunTest(CompositorMode mode, bool delegating_renderer) {
}
void LayerTreeTest::RequestNewOutputSurface() {
- layer_tree_host_->SetOutputSurface(CreateOutputSurface());
+ SetOutputSurfaceOnLayerTreeHost(CreateOutputSurface());
}
scoped_ptr<OutputSurface> LayerTreeTest::CreateOutputSurface() {
diff --git a/cc/test/layer_tree_test.h b/cc/test/layer_tree_test.h
index d2f1bd5..da70a06 100644
--- a/cc/test/layer_tree_test.h
+++ b/cc/test/layer_tree_test.h
@@ -130,6 +130,11 @@ class LayerTreeTest : public testing::Test, public TestHooks {
void DispatchCompositeImmediately();
void DispatchNextCommitWaitsForActivation();
+ void SetOutputSurfaceOnLayerTreeHost(
+ scoped_ptr<OutputSurface> output_surface);
+ scoped_ptr<OutputSurface> ReleaseOutputSurfaceOnLayerTreeHost();
+ void SetVisibleOnLayerTreeHost(bool visible);
+
virtual void AfterTest() = 0;
virtual void WillBeginTest();
virtual void BeginTest() = 0;
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc
index 529beae..8223474 100644
--- a/cc/trees/layer_tree_host.cc
+++ b/cc/trees/layer_tree_host.cc
@@ -234,6 +234,13 @@ void LayerTreeHost::InitializeRemoteServer(
RemoteProtoChannel* remote_proto_channel,
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner) {
task_runner_provider_ = TaskRunnerProvider::Create(main_task_runner, nullptr);
+
+ // The LayerTreeHost on the server never requests the output surface since
+ // it is only needed on the client. Since ProxyMain aborts commits if
+ // output_surface_lost() is true, always assume we have the output surface
+ // on the server.
+ output_surface_lost_ = false;
+
InitializeProxy(ProxyMain::CreateRemote(remote_proto_channel, this,
task_runner_provider_.get()),
nullptr);
diff --git a/cc/trees/layer_tree_host_unittest_remote_server.cc b/cc/trees/layer_tree_host_unittest_remote_server.cc
new file mode 100644
index 0000000..d902cfa
--- /dev/null
+++ b/cc/trees/layer_tree_host_unittest_remote_server.cc
@@ -0,0 +1,97 @@
+// Copyright 2016 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/layer_tree_host.h"
+
+#include "base/thread_task_runner_handle.h"
+#include "cc/test/test_task_graph_runner.h"
+#include "cc/trees/layer_tree_host_client.h"
+#include "cc/trees/proxy_common.h"
+#include "cc/trees/proxy_main.h"
+#include "cc/trees/remote_proto_channel.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace cc {
+namespace {
+
+class LayerTreeHostTestRemoteServer : public testing::Test,
+ public RemoteProtoChannel,
+ public LayerTreeHostClient {
+ public:
+ LayerTreeHostTestRemoteServer() : calls_received_(0) {
+ LayerTreeHost::InitParams params;
+ params.client = this;
+ params.task_graph_runner = &task_graph_runner_;
+ params.settings = &settings_;
+ params.main_task_runner = base::ThreadTaskRunnerHandle::Get();
+ layer_tree_host_ = LayerTreeHost::CreateRemoteServer(this, &params);
+ }
+
+ ~LayerTreeHostTestRemoteServer() override {}
+
+ // LayerTreeHostClient implementation
+ void WillBeginMainFrame() override {}
+ void BeginMainFrame(const BeginFrameArgs& args) override {}
+ void BeginMainFrameNotExpectedSoon() override {}
+ void DidBeginMainFrame() override {}
+ void UpdateLayerTreeHost() override {}
+ void ApplyViewportDeltas(const gfx::Vector2dF& inner_delta,
+ const gfx::Vector2dF& outer_delta,
+ const gfx::Vector2dF& elastic_overscroll_delta,
+ float page_scale,
+ float top_controls_delta) override {}
+ void RequestNewOutputSurface() override { NOTREACHED(); }
+ void DidInitializeOutputSurface() override { NOTREACHED(); }
+ void DidFailToInitializeOutputSurface() override { NOTREACHED(); }
+ void WillCommit() override {}
+ void DidCommit() override {}
+ void DidCommitAndDrawFrame() override {}
+ void DidCompleteSwapBuffers() override {}
+ void RecordFrameTimingEvents(
+ scoped_ptr<FrameTimingTracker::CompositeTimingSet> composite_events,
+ scoped_ptr<FrameTimingTracker::MainFrameTimingSet> main_frame_events)
+ override{};
+ void DidCompletePageScaleAnimation() override {}
+ void SendBeginFramesToChildren(const BeginFrameArgs& args) override {}
+
+ // RemoteProtoChannel implementation
+ void SetProtoReceiver(RemoteProtoChannel::ProtoReceiver* receiver) override {
+ receiver_ = receiver;
+ }
+ void SendCompositorProto(const proto::CompositorMessage& proto) override {}
+
+ int calls_received_;
+ TestTaskGraphRunner task_graph_runner_;
+ LayerTreeSettings settings_;
+ scoped_ptr<LayerTreeHost> layer_tree_host_;
+ RemoteProtoChannel::ProtoReceiver* receiver_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(LayerTreeHostTestRemoteServer);
+};
+
+class LayerTreeHostTestRemoteServerBeginMainFrame
+ : public LayerTreeHostTestRemoteServer {
+ protected:
+ void BeginMainFrame(const BeginFrameArgs& args) override {
+ calls_received_++;
+ }
+};
+
+// Makes sure that the BeginMainFrame call is not aborted on the server.
+// See crbug.com/577301.
+TEST_F(LayerTreeHostTestRemoteServerBeginMainFrame, BeginMainFrameNotAborted) {
+ layer_tree_host_->SetVisible(true);
+
+ scoped_ptr<BeginMainFrameAndCommitState> begin_frame_state;
+ begin_frame_state.reset(new BeginMainFrameAndCommitState());
+ begin_frame_state->scroll_info.reset(new ScrollAndScaleSet());
+
+ static_cast<ProxyMain*>(layer_tree_host_->proxy())
+ ->BeginMainFrame(std::move(begin_frame_state));
+ EXPECT_EQ(calls_received_, 1);
+}
+
+} // namespace
+} // namespace cc
diff --git a/cc/trees/remote_channel_impl.cc b/cc/trees/remote_channel_impl.cc
index bde3202..e9db10b 100644
--- a/cc/trees/remote_channel_impl.cc
+++ b/cc/trees/remote_channel_impl.cc
@@ -26,8 +26,10 @@ scoped_ptr<RemoteChannelImpl> RemoteChannelImpl::Create(
RemoteChannelImpl::RemoteChannelImpl(LayerTreeHost* layer_tree_host,
RemoteProtoChannel* remote_proto_channel,
TaskRunnerProvider* task_runner_provider)
- : main_thread_vars_unsafe_(layer_tree_host, remote_proto_channel),
- task_runner_provider_(task_runner_provider) {
+ : task_runner_provider_(task_runner_provider),
+ main_thread_vars_unsafe_(this, layer_tree_host, remote_proto_channel),
+ compositor_thread_vars_unsafe_(
+ main().remote_channel_weak_factory.GetWeakPtr()) {
DCHECK(task_runner_provider_->IsMainThread());
main().remote_proto_channel->SetProtoReceiver(this);
@@ -92,6 +94,7 @@ bool RemoteChannelImpl::CommitToActiveTree() const {
void RemoteChannelImpl::SetOutputSurface(OutputSurface* output_surface) {
DCHECK(task_runner_provider_->IsMainThread());
+
ImplThreadTaskRunner()->PostTask(
FROM_HERE, base::Bind(&ProxyImpl::InitializeOutputSurfaceOnImpl,
proxy_impl_weak_ptr_, output_surface));
@@ -109,6 +112,7 @@ void RemoteChannelImpl::ReleaseOutputSurface() {
void RemoteChannelImpl::SetVisible(bool visible) {
DCHECK(task_runner_provider_->IsMainThread());
+
ImplThreadTaskRunner()->PostTask(
FROM_HERE,
base::Bind(&ProxyImpl::SetVisibleOnImpl, proxy_impl_weak_ptr_, visible));
@@ -205,6 +209,7 @@ void RemoteChannelImpl::Stop() {
}
main().started = false;
+ main().remote_channel_weak_factory.InvalidateWeakPtrs();
}
bool RemoteChannelImpl::SupportsImplScrolling() const {
@@ -253,13 +258,32 @@ void RemoteChannelImpl::DidCommitAndDrawFrame() {}
void RemoteChannelImpl::SetAnimationEvents(scoped_ptr<AnimationEvents> queue) {}
-void RemoteChannelImpl::DidLoseOutputSurface() {}
+void RemoteChannelImpl::DidLoseOutputSurface() {
+ DCHECK(task_runner_provider_->IsImplThread());
+
+ MainThreadTaskRunner()->PostTask(
+ FROM_HERE, base::Bind(&RemoteChannelImpl::DidLoseOutputSurfaceOnMain,
+ impl().remote_channel_weak_ptr));
+}
+
+void RemoteChannelImpl::RequestNewOutputSurface() {
+ DCHECK(task_runner_provider_->IsImplThread());
-void RemoteChannelImpl::RequestNewOutputSurface() {}
+ MainThreadTaskRunner()->PostTask(
+ FROM_HERE, base::Bind(&RemoteChannelImpl::RequestNewOutputSurfaceOnMain,
+ impl().remote_channel_weak_ptr));
+}
void RemoteChannelImpl::DidInitializeOutputSurface(
bool success,
- const RendererCapabilities& capabilities) {}
+ const RendererCapabilities& capabilities) {
+ DCHECK(task_runner_provider_->IsImplThread());
+
+ MainThreadTaskRunner()->PostTask(
+ FROM_HERE,
+ base::Bind(&RemoteChannelImpl::DidInitializeOutputSurfaceOnMain,
+ impl().remote_channel_weak_ptr, success, capabilities));
+}
void RemoteChannelImpl::DidCompletePageScaleAnimation() {}
@@ -270,6 +294,32 @@ void RemoteChannelImpl::PostFrameTimingEventsOnMain(
void RemoteChannelImpl::BeginMainFrame(
scoped_ptr<BeginMainFrameAndCommitState> begin_main_frame_state) {}
+void RemoteChannelImpl::DidLoseOutputSurfaceOnMain() {
+ DCHECK(task_runner_provider_->IsMainThread());
+
+ main().layer_tree_host->DidLoseOutputSurface();
+}
+
+void RemoteChannelImpl::RequestNewOutputSurfaceOnMain() {
+ DCHECK(task_runner_provider_->IsMainThread());
+
+ main().layer_tree_host->RequestNewOutputSurface();
+}
+
+void RemoteChannelImpl::DidInitializeOutputSurfaceOnMain(
+ bool success,
+ const RendererCapabilities& capabilities) {
+ DCHECK(task_runner_provider_->IsMainThread());
+
+ if (!success) {
+ main().layer_tree_host->DidFailToInitializeOutputSurface();
+ return;
+ }
+
+ main().renderer_capabilities = capabilities;
+ main().layer_tree_host->DidInitializeOutputSurface();
+}
+
void RemoteChannelImpl::InitializeImplOnImpl(CompletionEvent* completion,
LayerTreeHost* layer_tree_host) {
DCHECK(task_runner_provider_->IsMainThreadBlocked());
@@ -325,19 +375,24 @@ base::SingleThreadTaskRunner* RemoteChannelImpl::ImplThreadTaskRunner() const {
}
RemoteChannelImpl::MainThreadOnly::MainThreadOnly(
+ RemoteChannelImpl* remote_channel_impl,
LayerTreeHost* layer_tree_host,
RemoteProtoChannel* remote_proto_channel)
: layer_tree_host(layer_tree_host),
remote_proto_channel(remote_proto_channel),
- started(false) {
+ started(false),
+ remote_channel_weak_factory(remote_channel_impl) {
DCHECK(layer_tree_host);
DCHECK(remote_proto_channel);
}
RemoteChannelImpl::MainThreadOnly::~MainThreadOnly() {}
-RemoteChannelImpl::CompositorThreadOnly::CompositorThreadOnly()
- : proxy_impl(nullptr), proxy_impl_weak_factory(nullptr) {}
+RemoteChannelImpl::CompositorThreadOnly::CompositorThreadOnly(
+ base::WeakPtr<RemoteChannelImpl> remote_channel_weak_ptr)
+ : proxy_impl(nullptr),
+ proxy_impl_weak_factory(nullptr),
+ remote_channel_weak_ptr(remote_channel_weak_ptr) {}
RemoteChannelImpl::CompositorThreadOnly::~CompositorThreadOnly() {}
diff --git a/cc/trees/remote_channel_impl.h b/cc/trees/remote_channel_impl.h
index cb5430b..4b37f60 100644
--- a/cc/trees/remote_channel_impl.h
+++ b/cc/trees/remote_channel_impl.h
@@ -105,7 +105,10 @@ class CC_EXPORT RemoteChannelImpl : public ChannelImpl,
RendererCapabilities renderer_capabilities;
- MainThreadOnly(LayerTreeHost* layer_tree_host,
+ base::WeakPtrFactory<RemoteChannelImpl> remote_channel_weak_factory;
+
+ MainThreadOnly(RemoteChannelImpl*,
+ LayerTreeHost* layer_tree_host,
RemoteProtoChannel* remote_proto_channel);
~MainThreadOnly();
};
@@ -113,8 +116,10 @@ class CC_EXPORT RemoteChannelImpl : public ChannelImpl,
struct CompositorThreadOnly {
scoped_ptr<ProxyImpl> proxy_impl;
scoped_ptr<base::WeakPtrFactory<ProxyImpl>> proxy_impl_weak_factory;
+ base::WeakPtr<RemoteChannelImpl> remote_channel_weak_ptr;
- CompositorThreadOnly();
+ CompositorThreadOnly(
+ base::WeakPtr<RemoteChannelImpl> remote_channel_weak_ptr);
~CompositorThreadOnly();
};
@@ -174,6 +179,11 @@ class CC_EXPORT RemoteChannelImpl : public ChannelImpl,
// called on main thread.
void HandleProto(const proto::CompositorMessageToImpl& proto);
+ void DidLoseOutputSurfaceOnMain();
+ void RequestNewOutputSurfaceOnMain();
+ void DidInitializeOutputSurfaceOnMain(
+ bool success,
+ const RendererCapabilities& capabilities);
void InitializeImplOnImpl(CompletionEvent* completion,
LayerTreeHost* layer_tree_host);
@@ -187,12 +197,12 @@ class CC_EXPORT RemoteChannelImpl : public ChannelImpl,
base::SingleThreadTaskRunner* MainThreadTaskRunner() const;
base::SingleThreadTaskRunner* ImplThreadTaskRunner() const;
+ TaskRunnerProvider* task_runner_provider_;
+
// use accessors instead of these variables directly
MainThreadOnly main_thread_vars_unsafe_;
CompositorThreadOnly compositor_thread_vars_unsafe_;
- TaskRunnerProvider* task_runner_provider_;
-
base::WeakPtr<ProxyImpl> proxy_impl_weak_ptr_;
DISALLOW_COPY_AND_ASSIGN(RemoteChannelImpl);
diff --git a/cc/trees/remote_channel_main.cc b/cc/trees/remote_channel_main.cc
index 27fce830..8c1382f 100644
--- a/cc/trees/remote_channel_main.cc
+++ b/cc/trees/remote_channel_main.cc
@@ -52,7 +52,9 @@ void RemoteChannelMain::UpdateTopControlsStateOnImpl(
bool animate) {}
void RemoteChannelMain::InitializeOutputSurfaceOnImpl(
- OutputSurface* output_surface) {}
+ OutputSurface* output_surface) {
+ NOTREACHED() << "Should not be called on the server LayerTreeHost";
+}
void RemoteChannelMain::MainThreadHasStoppedFlingingOnImpl() {
proto::CompositorMessage proto;
@@ -71,10 +73,13 @@ void RemoteChannelMain::FinishAllRenderingOnImpl(CompletionEvent* completion) {
completion->Signal();
}
-void RemoteChannelMain::SetVisibleOnImpl(bool visible) {}
+void RemoteChannelMain::SetVisibleOnImpl(bool visible) {
+ NOTIMPLEMENTED() << "Visibility is not controlled by the server";
+}
void RemoteChannelMain::ReleaseOutputSurfaceOnImpl(
CompletionEvent* completion) {
+ NOTREACHED() << "Should not be called on the server LayerTreeHost";
completion->Signal();
}
diff --git a/cc/trees/remote_channel_unittest.cc b/cc/trees/remote_channel_unittest.cc
index 5c0989f..79a1d1c 100644
--- a/cc/trees/remote_channel_unittest.cc
+++ b/cc/trees/remote_channel_unittest.cc
@@ -24,6 +24,32 @@ class RemoteChannelTest : public LayerTreeTest {
DISALLOW_COPY_AND_ASSIGN(RemoteChannelTest);
};
+class RemoteChannelTestInitializationAndShutdown : public RemoteChannelTest {
+ void SetVisibleOnImpl(bool visible) override { calls_received_++; }
+
+ void RequestNewOutputSurface() override {
+ LayerTreeTest::RequestNewOutputSurface();
+ calls_received_++;
+ }
+
+ void InitializeOutputSurfaceOnImpl(OutputSurface* output_surface) override {
+ calls_received_++;
+ }
+
+ void DidInitializeOutputSurface() override {
+ calls_received_++;
+ EndTest();
+ }
+
+ void FinishGLOnImpl() override { calls_received_++; }
+
+ // On initialization and shutdown, each of the above calls should happen only
+ // once.
+ void AfterTest() override { EXPECT_EQ(5, calls_received_); }
+};
+
+REMOTE_DIRECT_RENDERER_TEST_F(RemoteChannelTestInitializationAndShutdown);
+
class RemoteChannelTestMainThreadStoppedFlinging : public RemoteChannelTest {
void BeginChannelTest() override { proxy()->MainThreadHasStoppedFlinging(); }