diff options
author | khushalsagar <khushalsagar@chromium.org> | 2016-01-29 18:47:17 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-01-30 02:48:18 +0000 |
commit | b0d8691b17203c4e033ff5ee1a98a9de99a66734 (patch) | |
tree | 7f12cbbd1e2e5601de472dd80070243015158afd | |
parent | a5c40ea4cf0e867757dfb4741c9a1ef838b8f82f (diff) | |
download | chromium_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.gn | 1 | ||||
-rw-r--r-- | cc/cc_tests.gyp | 1 | ||||
-rw-r--r-- | cc/test/layer_tree_test.cc | 33 | ||||
-rw-r--r-- | cc/test/layer_tree_test.h | 5 | ||||
-rw-r--r-- | cc/trees/layer_tree_host.cc | 7 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_unittest_remote_server.cc | 97 | ||||
-rw-r--r-- | cc/trees/remote_channel_impl.cc | 71 | ||||
-rw-r--r-- | cc/trees/remote_channel_impl.h | 18 | ||||
-rw-r--r-- | cc/trees/remote_channel_main.cc | 9 | ||||
-rw-r--r-- | cc/trees/remote_channel_unittest.cc | 26 |
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, ¶ms); + } + + ~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(); } |