diff options
author | sievers@google.com <sievers@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-12-19 18:56:07 +0000 |
---|---|---|
committer | sievers@google.com <sievers@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-12-19 18:56:07 +0000 |
commit | e96e34372428b9e0f0d76382b02c62c123ee00a5 (patch) | |
tree | 3022527916900b19e41b0a8e4d21b2e1d75a3999 /cc | |
parent | e7d6293bf36c2e3c23c5789530ccfb4b99332daa (diff) | |
download | chromium_src-e96e34372428b9e0f0d76382b02c62c123ee00a5.zip chromium_src-e96e34372428b9e0f0d76382b02c62c123ee00a5.tar.gz chromium_src-e96e34372428b9e0f0d76382b02c62c123ee00a5.tar.bz2 |
cc: Defer first OutputSurface creation until client is ready
Remove the |first_output_surface| which was not used before
the client signals ready.
This allows the client to wait before creating a graphics context
until the gpu thread and client channel are set up.
BUG=270179,329739
R=danakj@chromium.org, jamesr@chromium.org, jochen@chromium.org
Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=238458
Review URL: https://codereview.chromium.org/85693007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@241897 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc')
-rw-r--r-- | cc/test/fake_proxy.h | 2 | ||||
-rw-r--r-- | cc/test/layer_tree_test.cc | 12 | ||||
-rw-r--r-- | cc/test/layer_tree_test.h | 9 | ||||
-rw-r--r-- | cc/trees/layer_tree_host.cc | 28 | ||||
-rw-r--r-- | cc/trees/layer_tree_host.h | 8 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_unittest.cc | 2 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_unittest_context.cc | 165 | ||||
-rw-r--r-- | cc/trees/proxy.h | 2 | ||||
-rw-r--r-- | cc/trees/single_thread_proxy.cc | 9 | ||||
-rw-r--r-- | cc/trees/single_thread_proxy.h | 6 | ||||
-rw-r--r-- | cc/trees/thread_proxy.cc | 9 | ||||
-rw-r--r-- | cc/trees/thread_proxy.h | 5 |
12 files changed, 164 insertions, 93 deletions
diff --git a/cc/test/fake_proxy.h b/cc/test/fake_proxy.h index bcde11e..295cd9d 100644 --- a/cc/test/fake_proxy.h +++ b/cc/test/fake_proxy.h @@ -38,7 +38,7 @@ class FakeProxy : public Proxy { virtual void MainThreadHasStoppedFlinging() OVERRIDE {} virtual bool BeginMainFrameRequested() const OVERRIDE; virtual bool CommitRequested() const OVERRIDE; - virtual void Start(scoped_ptr<OutputSurface> first_output_surface) OVERRIDE {} + virtual void Start() OVERRIDE {} virtual void Stop() OVERRIDE {} virtual void ForceSerializeOnSwapBuffers() OVERRIDE {} virtual size_t MaxPartialTextureUpdates() const OVERRIDE; diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc index 64c3e9a..95758c2 100644 --- a/cc/test/layer_tree_test.cc +++ b/cc/test/layer_tree_test.cc @@ -293,12 +293,10 @@ class LayerTreeHostForTesting : public LayerTreeHost { scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner) { scoped_ptr<LayerTreeHostForTesting> layer_tree_host( new LayerTreeHostForTesting(test_hooks, client, settings)); - bool success; if (impl_task_runner.get()) - success = layer_tree_host->InitializeThreaded(impl_task_runner); + layer_tree_host->InitializeThreaded(impl_task_runner); else - success = layer_tree_host->InitializeSingleThreaded(client); - EXPECT_TRUE(success); + layer_tree_host->InitializeSingleThreaded(client); return layer_tree_host.Pass(); } @@ -463,6 +461,10 @@ void LayerTreeTest::PostSetNextCommitForcesRedrawToMainThread() { main_thread_weak_ptr_)); } +void LayerTreeTest::WillBeginTest() { + layer_tree_host_->SetLayerTreeHostClientReady(); +} + void LayerTreeTest::DoBeginTest() { client_ = LayerTreeHostClientForTesting::Create(this); @@ -477,7 +479,7 @@ void LayerTreeTest::DoBeginTest() { started_ = true; beginning_ = true; SetupTree(); - layer_tree_host_->SetLayerTreeHostClientReady(); + WillBeginTest(); BeginTest(); beginning_ = false; if (end_when_begin_returns_) diff --git a/cc/test/layer_tree_test.h b/cc/test/layer_tree_test.h index 1e58dd9..f774d98 100644 --- a/cc/test/layer_tree_test.h +++ b/cc/test/layer_tree_test.h @@ -111,10 +111,6 @@ class LayerTreeTest : public testing::Test, public TestHooks { public: virtual ~LayerTreeTest(); - virtual void AfterTest() = 0; - virtual void BeginTest() = 0; - virtual void SetupTree(); - virtual void EndTest(); void EndTestAfterDelay(int delay_milliseconds); @@ -155,6 +151,11 @@ class LayerTreeTest : public testing::Test, public TestHooks { void DispatchComposite(); void DispatchDidAddAnimation(); + virtual void AfterTest() = 0; + virtual void WillBeginTest(); + virtual void BeginTest() = 0; + virtual void SetupTree(); + virtual void RunTest(bool threaded, bool delegating_renderer, bool impl_side_painting); diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc index 7432197..0bf7124 100644 --- a/cc/trees/layer_tree_host.cc +++ b/cc/trees/layer_tree_host.cc @@ -69,8 +69,7 @@ scoped_ptr<LayerTreeHost> LayerTreeHost::CreateThreaded( DCHECK(impl_task_runner); scoped_ptr<LayerTreeHost> layer_tree_host( new LayerTreeHost(client, manager, settings)); - if (!layer_tree_host->InitializeThreaded(impl_task_runner)) - return scoped_ptr<LayerTreeHost>(); + layer_tree_host->InitializeThreaded(impl_task_runner); return layer_tree_host.Pass(); } @@ -81,8 +80,7 @@ scoped_ptr<LayerTreeHost> LayerTreeHost::CreateSingleThreaded( const LayerTreeSettings& settings) { scoped_ptr<LayerTreeHost> layer_tree_host( new LayerTreeHost(client, manager, settings)); - if (!layer_tree_host->InitializeSingleThreaded(single_thread_client)) - return scoped_ptr<LayerTreeHost>(); + layer_tree_host->InitializeSingleThreaded(single_thread_client); return layer_tree_host.Pass(); } @@ -125,31 +123,25 @@ LayerTreeHost::LayerTreeHost( debug_state_.RecordRenderingStats()); } -bool LayerTreeHost::InitializeThreaded( +void LayerTreeHost::InitializeThreaded( scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner) { - return InitializeProxy(ThreadProxy::Create(this, impl_task_runner)); + InitializeProxy(ThreadProxy::Create(this, impl_task_runner)); } -bool LayerTreeHost::InitializeSingleThreaded( +void LayerTreeHost::InitializeSingleThreaded( LayerTreeHostSingleThreadClient* single_thread_client) { - return InitializeProxy( - SingleThreadProxy::Create(this, single_thread_client)); + InitializeProxy(SingleThreadProxy::Create(this, single_thread_client)); } -bool LayerTreeHost::InitializeForTesting(scoped_ptr<Proxy> proxy_for_testing) { - return InitializeProxy(proxy_for_testing.Pass()); +void LayerTreeHost::InitializeForTesting(scoped_ptr<Proxy> proxy_for_testing) { + InitializeProxy(proxy_for_testing.Pass()); } -bool LayerTreeHost::InitializeProxy(scoped_ptr<Proxy> proxy) { +void LayerTreeHost::InitializeProxy(scoped_ptr<Proxy> proxy) { TRACE_EVENT0("cc", "LayerTreeHost::InitializeForReal"); - scoped_ptr<OutputSurface> output_surface(CreateOutputSurface()); - if (!output_surface) - return false; - proxy_ = proxy.Pass(); - proxy_->Start(output_surface.Pass()); - return true; + proxy_->Start(); } LayerTreeHost::~LayerTreeHost() { diff --git a/cc/trees/layer_tree_host.h b/cc/trees/layer_tree_host.h index 8b9c1cf..e66cd06 100644 --- a/cc/trees/layer_tree_host.h +++ b/cc/trees/layer_tree_host.h @@ -303,11 +303,11 @@ class CC_EXPORT LayerTreeHost { LayerTreeHost(LayerTreeHostClient* client, SharedBitmapManager* manager, const LayerTreeSettings& settings); - bool InitializeThreaded( + void InitializeThreaded( scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner); - bool InitializeSingleThreaded( + void InitializeSingleThreaded( LayerTreeHostSingleThreadClient* single_thread_client); - bool InitializeForTesting(scoped_ptr<Proxy> proxy_for_testing); + void InitializeForTesting(scoped_ptr<Proxy> proxy_for_testing); void SetOutputSurfaceLostForTesting(bool is_lost) { output_surface_lost_ = is_lost; } @@ -315,7 +315,7 @@ class CC_EXPORT LayerTreeHost { MicroBenchmarkController micro_benchmark_controller_; private: - bool InitializeProxy(scoped_ptr<Proxy> proxy); + void InitializeProxy(scoped_ptr<Proxy> proxy); void PaintLayerContents( const RenderSurfaceLayerList& render_surface_layer_list, diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc index 0ac203a..c7ca4be 100644 --- a/cc/trees/layer_tree_host_unittest.cc +++ b/cc/trees/layer_tree_host_unittest.cc @@ -2308,7 +2308,7 @@ class LayerTreeHostWithProxy : public LayerTreeHost { scoped_ptr<FakeProxy> proxy) : LayerTreeHost(client, NULL, settings) { proxy->SetLayerTreeHost(this); - EXPECT_TRUE(InitializeForTesting(proxy.PassAs<Proxy>())); + InitializeForTesting(proxy.PassAs<Proxy>()); } }; diff --git a/cc/trees/layer_tree_host_unittest_context.cc b/cc/trees/layer_tree_host_unittest_context.cc index 7112436..a3564de 100644 --- a/cc/trees/layer_tree_host_unittest_context.cc +++ b/cc/trees/layer_tree_host_unittest_context.cc @@ -345,6 +345,37 @@ class LayerTreeHostContextTestLostContextSucceeds SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostContextTestLostContextSucceeds); +class LayerTreeHostClientNotReadyDoesNotCreateOutputSurface + : public LayerTreeHostContextTest { + public: + LayerTreeHostClientNotReadyDoesNotCreateOutputSurface() + : LayerTreeHostContextTest() {} + + virtual void WillBeginTest() OVERRIDE { + // Override and do not signal SetLayerTreeHostClientReady. + } + + virtual void BeginTest() OVERRIDE { + PostSetNeedsCommitToMainThread(); + EndTest(); + } + + virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback) + OVERRIDE { + EXPECT_TRUE(false); + return scoped_ptr<OutputSurface>(); + } + + virtual void DidInitializeOutputSurface(bool succeeded) OVERRIDE { + EXPECT_TRUE(false); + } + + virtual void AfterTest() OVERRIDE { + } +}; + +MULTI_THREAD_TEST_F(LayerTreeHostClientNotReadyDoesNotCreateOutputSurface); + class LayerTreeHostContextTestLostContextSucceedsWithContent : public LayerTreeHostContextTestLostContextSucceeds { public: @@ -461,6 +492,97 @@ TEST_F(LayerTreeHostContextTestLostContextSucceedsWithContent, RunTest(true, false, false); } +class LayerTreeHostContextTestCreateOutputSurfaceFails + : public LayerTreeHostContextTest { + public: + // Run a test that initially fails OutputSurface creation |times_to_fail| + // times. If |expect_fallback_attempt| is |true|, an attempt to create a + // fallback/software OutputSurface is expected to occur. + LayerTreeHostContextTestCreateOutputSurfaceFails(int times_to_fail, + bool expect_fallback_attempt, + bool expect_to_give_up) + : times_to_fail_(times_to_fail), + expect_fallback_attempt_(expect_fallback_attempt), + expect_to_give_up_(expect_to_give_up), + did_attempt_fallback_(false), + times_initialized_(0) {} + + virtual void BeginTest() OVERRIDE { + times_to_fail_create_ = times_to_fail_; + PostSetNeedsCommitToMainThread(); + } + + virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback) + OVERRIDE { + scoped_ptr<OutputSurface> surface = + LayerTreeHostContextTest::CreateOutputSurface(fallback); + + if (surface) + EXPECT_EQ(times_to_fail_, times_create_failed_); + + did_attempt_fallback_ = fallback; + return surface.Pass(); + } + + virtual void DidInitializeOutputSurface(bool succeeded) OVERRIDE { + if (succeeded) + times_initialized_++; + else + EndTest(); + } + + virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + EndTest(); + } + + virtual void AfterTest() OVERRIDE { + EXPECT_EQ(times_to_fail_, times_create_failed_); + EXPECT_EQ(expect_to_give_up_, times_initialized_ == 0); + EXPECT_EQ(expect_fallback_attempt_, did_attempt_fallback_); + } + + private: + int times_to_fail_; + bool expect_fallback_attempt_; + bool expect_to_give_up_; + bool did_attempt_fallback_; + int times_initialized_; +}; + +class LayerTreeHostContextTestCreateOutputSurfaceFailsOnce + : public LayerTreeHostContextTestCreateOutputSurfaceFails { + public: + LayerTreeHostContextTestCreateOutputSurfaceFailsOnce() + : LayerTreeHostContextTestCreateOutputSurfaceFails(1, false, false) {} +}; + +SINGLE_AND_MULTI_THREAD_TEST_F( + LayerTreeHostContextTestCreateOutputSurfaceFailsOnce); + +// After 4 failures we expect an attempt to create a fallback/software +// OutputSurface. +class LayerTreeHostContextTestCreateOutputSurfaceFailsWithFallback + : public LayerTreeHostContextTestCreateOutputSurfaceFails { + public: + LayerTreeHostContextTestCreateOutputSurfaceFailsWithFallback() + : LayerTreeHostContextTestCreateOutputSurfaceFails(4, true, false) {} +}; + +SINGLE_AND_MULTI_THREAD_TEST_F( + LayerTreeHostContextTestCreateOutputSurfaceFailsWithFallback); + +// If we fail that often, we should be giving up cleanly. +class LayerTreeHostContextTestCreateOutputSurfaceIsHopeless + : public LayerTreeHostContextTestCreateOutputSurfaceFails { + public: + LayerTreeHostContextTestCreateOutputSurfaceIsHopeless() + : LayerTreeHostContextTestCreateOutputSurfaceFails(5, true, true) {} +}; + +SINGLE_AND_MULTI_THREAD_TEST_F( + LayerTreeHostContextTestCreateOutputSurfaceIsHopeless); + + class LayerTreeHostContextTestOffscreenContextFails : public LayerTreeHostContextTest { public: @@ -1032,7 +1154,11 @@ class LayerTreeHostContextTestDontUseLostResources virtual scoped_ptr<OutputSurface> CreateOutputSurface( bool fallback) OVERRIDE { - if (layer_tree_host()) { + // This will get called twice: + // First when we create the initial output surface... + if (layer_tree_host()->source_frame_number() > 0) { + // ... and then again after we forced the context to be lost on the third + // frame. Verify this assumption here. lost_context_ = true; EXPECT_EQ(layer_tree_host()->source_frame_number(), 3); } @@ -1405,43 +1531,6 @@ class ScrollbarLayerLostContext : public LayerTreeHostContextTest { SINGLE_AND_MULTI_THREAD_TEST_F(ScrollbarLayerLostContext); -// Not reusing LayerTreeTest because it expects creating LTH to always succeed. -class LayerTreeHostTestCannotCreateIfCannotCreateOutputSurface - : public testing::Test, - public FakeLayerTreeHostClient { - public: - LayerTreeHostTestCannotCreateIfCannotCreateOutputSurface() - : FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D) {} - - // FakeLayerTreeHostClient implementation. - virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback) - OVERRIDE { - return scoped_ptr<OutputSurface>(); - } - - void RunTest(bool threaded, - bool delegating_renderer, - bool impl_side_painting) { - LayerTreeSettings settings; - settings.impl_side_painting = impl_side_painting; - if (threaded) { - scoped_ptr<base::Thread> impl_thread(new base::Thread("LayerTreeTest")); - ASSERT_TRUE(impl_thread->Start()); - ASSERT_TRUE(impl_thread->message_loop_proxy().get()); - scoped_ptr<LayerTreeHost> layer_tree_host = LayerTreeHost::CreateThreaded( - this, NULL, settings, impl_thread->message_loop_proxy()); - EXPECT_FALSE(layer_tree_host); - } else { - scoped_ptr<LayerTreeHost> layer_tree_host = - LayerTreeHost::CreateSingleThreaded(this, this, NULL, settings); - EXPECT_FALSE(layer_tree_host); - } - } -}; - -SINGLE_AND_MULTI_THREAD_TEST_F( - LayerTreeHostTestCannotCreateIfCannotCreateOutputSurface); - class UIResourceLostTest : public LayerTreeHostContextTest { public: UIResourceLostTest() : time_step_(0) {} diff --git a/cc/trees/proxy.h b/cc/trees/proxy.h index 69975a6..8949a02 100644 --- a/cc/trees/proxy.h +++ b/cc/trees/proxy.h @@ -84,7 +84,7 @@ class CC_EXPORT Proxy { virtual bool BeginMainFrameRequested() const = 0; // Must be called before using the proxy. - virtual void Start(scoped_ptr<OutputSurface> first_output_surface) = 0; + virtual void Start() = 0; virtual void Stop() = 0; // Must be called before deleting the proxy. // Forces 3D commands on all contexts to wait for all previous SwapBuffers diff --git a/cc/trees/single_thread_proxy.cc b/cc/trees/single_thread_proxy.cc index f1f8a4f..e7dd9f1 100644 --- a/cc/trees/single_thread_proxy.cc +++ b/cc/trees/single_thread_proxy.cc @@ -44,11 +44,9 @@ SingleThreadProxy::SingleThreadProxy(LayerTreeHost* layer_tree_host, << "Threaded compositing must be enabled to use impl-side painting."; } -void SingleThreadProxy::Start(scoped_ptr<OutputSurface> first_output_surface) { - DCHECK(first_output_surface); +void SingleThreadProxy::Start() { DebugScopedSetImplThread impl(this); layer_tree_host_impl_ = layer_tree_host_->CreateLayerTreeHostImpl(this); - first_output_surface_ = first_output_surface.Pass(); } SingleThreadProxy::~SingleThreadProxy() { @@ -113,9 +111,8 @@ void SingleThreadProxy::CreateAndInitializeOutputSurface() { "cc", "SingleThreadProxy::CreateAndInitializeOutputSurface"); DCHECK(Proxy::IsMainThread()); - scoped_ptr<OutputSurface> output_surface = first_output_surface_.Pass(); - if (!output_surface) - output_surface = layer_tree_host_->CreateOutputSurface(); + scoped_ptr<OutputSurface> output_surface = + layer_tree_host_->CreateOutputSurface(); if (!output_surface) { OnOutputSurfaceInitializeAttempted(false); return; diff --git a/cc/trees/single_thread_proxy.h b/cc/trees/single_thread_proxy.h index 463141c..9d382a4 100644 --- a/cc/trees/single_thread_proxy.h +++ b/cc/trees/single_thread_proxy.h @@ -44,7 +44,7 @@ class SingleThreadProxy : public Proxy, LayerTreeHostImplClient { virtual bool CommitRequested() const OVERRIDE; virtual bool BeginMainFrameRequested() const OVERRIDE; virtual void MainThreadHasStoppedFlinging() OVERRIDE {} - virtual void Start(scoped_ptr<OutputSurface> first_output_surface) OVERRIDE; + virtual void Start() OVERRIDE; virtual void Stop() OVERRIDE; virtual size_t MaxPartialTextureUpdates() const OVERRIDE; virtual void AcquireLayerTextures() OVERRIDE {} @@ -107,10 +107,6 @@ class SingleThreadProxy : public Proxy, LayerTreeHostImplClient { LayerTreeHostSingleThreadClient* client_; bool created_offscreen_context_provider_; - // Holds the first output surface passed from Start. Should not be used for - // anything else. - scoped_ptr<OutputSurface> first_output_surface_; - // Used on the Thread, but checked on main thread during // initialization/shutdown. scoped_ptr<LayerTreeHostImpl> layer_tree_host_impl_; diff --git a/cc/trees/thread_proxy.cc b/cc/trees/thread_proxy.cc index 2823182..0518a6b 100644 --- a/cc/trees/thread_proxy.cc +++ b/cc/trees/thread_proxy.cc @@ -266,9 +266,8 @@ void ThreadProxy::DoCreateAndInitializeOutputSurface() { TRACE_EVENT0("cc", "ThreadProxy::DoCreateAndInitializeOutputSurface"); DCHECK(IsMainThread()); - scoped_ptr<OutputSurface> output_surface = first_output_surface_.Pass(); - if (!output_surface) - output_surface = layer_tree_host()->CreateOutputSurface(); + scoped_ptr<OutputSurface> output_surface = + layer_tree_host()->CreateOutputSurface(); RendererCapabilities capabilities; bool success = !!output_surface; @@ -641,10 +640,9 @@ ThreadProxy::contents_texture_manager_on_impl_thread() { return contents_texture_manager_unsafe_; } -void ThreadProxy::Start(scoped_ptr<OutputSurface> first_output_surface) { +void ThreadProxy::Start() { DCHECK(IsMainThread()); DCHECK(Proxy::HasImplThread()); - DCHECK(first_output_surface); // Create LayerTreeHostImpl. DebugScopedSetMainThreadBlocked main_thread_blocked(this); @@ -657,7 +655,6 @@ void ThreadProxy::Start(scoped_ptr<OutputSurface> first_output_surface) { completion.Wait(); main_thread_weak_ptr_ = weak_factory_.GetWeakPtr(); - first_output_surface_ = first_output_surface.Pass(); started_ = true; } diff --git a/cc/trees/thread_proxy.h b/cc/trees/thread_proxy.h index cf041ed..49cbb19 100644 --- a/cc/trees/thread_proxy.h +++ b/cc/trees/thread_proxy.h @@ -58,7 +58,7 @@ class ThreadProxy : public Proxy, virtual bool CommitRequested() const OVERRIDE; virtual bool BeginMainFrameRequested() const OVERRIDE; virtual void MainThreadHasStoppedFlinging() OVERRIDE; - virtual void Start(scoped_ptr<OutputSurface> first_output_surface) OVERRIDE; + virtual void Start() OVERRIDE; virtual void Stop() OVERRIDE; virtual size_t MaxPartialTextureUpdates() const OVERRIDE; virtual void AcquireLayerTextures() OVERRIDE; @@ -224,9 +224,6 @@ class ThreadProxy : public Proxy, bool manage_tiles_pending_; // Weak pointer to use when posting tasks to the impl thread. base::WeakPtr<ThreadProxy> impl_thread_weak_ptr_; - // Holds the first output surface passed from Start. Should not be used for - // anything else. - scoped_ptr<OutputSurface> first_output_surface_; // Accessed on the main thread, or when main thread is blocked. bool commit_waits_for_activation_; |