diff options
author | enne@chromium.org <enne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-08-13 22:36:06 +0000 |
---|---|---|
committer | enne@chromium.org <enne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-08-13 22:37:22 +0000 |
commit | 2decdd7866eea2d446a0e4873c070bcfc5f6fb8f (patch) | |
tree | bb8b35fc963e9e636fc5ebcdec3f996e7efd51a5 | |
parent | e838828785661869db162ef8316e271a48ec6b17 (diff) | |
download | chromium_src-2decdd7866eea2d446a0e4873c070bcfc5f6fb8f.zip chromium_src-2decdd7866eea2d446a0e4873c070bcfc5f6fb8f.tar.gz chromium_src-2decdd7866eea2d446a0e4873c070bcfc5f6fb8f.tar.bz2 |
Revert "Make SingleThreadProxy a SchedulerClient"
This reverts commit r288866 because of crashes.
Old patch: https://codereview.chromium.org/134623005/
NOTRY=true
TBR=danakj@chromium.org,boliu@chromium.org,piman@chromium.org,ben@chromium.org
BUG=402943,403400
Review URL: https://codereview.chromium.org/475483002
Cr-Commit-Position: refs/heads/master@{#289395}
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@289395 0039d316-1c4b-4281-b951-d872f2087c98
42 files changed, 479 insertions, 665 deletions
diff --git a/android_webview/browser/hardware_renderer.cc b/android_webview/browser/hardware_renderer.cc index d4c28b9..5fb527f 100644 --- a/android_webview/browser/hardware_renderer.cc +++ b/android_webview/browser/hardware_renderer.cc @@ -95,9 +95,6 @@ HardwareRenderer::HardwareRenderer(SharedRendererState* state) // Webview does not own the surface so should not clear it. settings.should_clear_root_render_pass = false; - // TODO(enne): Update this this compositor to use a synchronous scheduler. - settings.single_thread_proxy_scheduler = false; - layer_tree_host_ = cc::LayerTreeHost::CreateSingleThreaded(this, this, NULL, settings, NULL); layer_tree_host_->SetRootLayer(root_layer_); diff --git a/android_webview/browser/hardware_renderer.h b/android_webview/browser/hardware_renderer.h index b07d36d..f87890b 100644 --- a/android_webview/browser/hardware_renderer.h +++ b/android_webview/browser/hardware_renderer.h @@ -54,6 +54,8 @@ class HardwareRenderer : public cc::LayerTreeHostClient, virtual void DidCompleteSwapBuffers() OVERRIDE {} // cc::LayerTreeHostSingleThreadClient overrides. + virtual void ScheduleComposite() OVERRIDE {} + virtual void ScheduleAnimation() OVERRIDE {} virtual void DidPostSwapBuffers() OVERRIDE {} virtual void DidAbortSwapBuffers() OVERRIDE {} diff --git a/cc/BUILD.gn b/cc/BUILD.gn index 7c1254a..ddabbdd 100644 --- a/cc/BUILD.gn +++ b/cc/BUILD.gn @@ -452,7 +452,6 @@ component("cc") { "trees/proxy.h", "trees/proxy_timing_history.cc", "trees/proxy_timing_history.h", - "trees/scoped_abort_remaining_swap_promises.h", "trees/single_thread_proxy.cc", "trees/single_thread_proxy.h", "trees/thread_proxy.cc", @@ -481,7 +481,6 @@ 'trees/proxy.h', 'trees/proxy_timing_history.cc', 'trees/proxy_timing_history.h', - 'trees/scoped_abort_remaining_swap_promises.h', 'trees/single_thread_proxy.cc', 'trees/single_thread_proxy.h', 'trees/thread_proxy.cc', diff --git a/cc/scheduler/scheduler.cc b/cc/scheduler/scheduler.cc index a20bfd2b..1451237 100644 --- a/cc/scheduler/scheduler.cc +++ b/cc/scheduler/scheduler.cc @@ -79,11 +79,11 @@ Scheduler::Scheduler( SchedulerClient* client, const SchedulerSettings& scheduler_settings, int layer_tree_host_id, - const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) + const scoped_refptr<base::SingleThreadTaskRunner>& impl_task_runner) : settings_(scheduler_settings), client_(client), layer_tree_host_id_(layer_tree_host_id), - task_runner_(task_runner), + impl_task_runner_(impl_task_runner), vsync_interval_(BeginFrameArgs::DefaultInterval()), last_set_needs_begin_frame_(false), begin_unthrottled_frame_posted_(false), @@ -128,7 +128,7 @@ Scheduler::~Scheduler() { void Scheduler::SetupSyntheticBeginFrames() { DCHECK(!synthetic_begin_frame_source_); synthetic_begin_frame_source_.reset( - new SyntheticBeginFrameSource(this, task_runner_.get())); + new SyntheticBeginFrameSource(this, impl_task_runner_.get())); } void Scheduler::CommitVSyncParameters(base::TimeTicks timebase, @@ -274,9 +274,6 @@ base::TimeTicks Scheduler::LastBeginImplFrameTime() { } void Scheduler::SetupNextBeginFrameIfNeeded() { - if (!task_runner_) - return; - bool needs_begin_frame = state_machine_.BeginFrameNeeded(); if (settings_.throttle_frame_production) { @@ -331,7 +328,7 @@ void Scheduler::SetupNextBeginFrameWhenVSyncThrottlingDisabled( } begin_unthrottled_frame_posted_ = true; - task_runner_->PostTask(FROM_HERE, begin_unthrottled_frame_closure_); + impl_task_runner_->PostTask(FROM_HERE, begin_unthrottled_frame_closure_); } // BeginUnthrottledFrame is used when we aren't throttling frame production. @@ -365,7 +362,7 @@ void Scheduler::SetupPollingMechanisms(bool needs_begin_frame) { base::TimeDelta delay = begin_impl_frame_args_.IsValid() ? begin_impl_frame_args_.interval : BeginFrameArgs::DefaultInterval(); - task_runner_->PostDelayedTask( + impl_task_runner_->PostDelayedTask( FROM_HERE, poll_for_draw_triggers_task_.callback(), delay); } } else { @@ -390,9 +387,9 @@ void Scheduler::SetupPollingMechanisms(bool needs_begin_frame) { // Since we'd rather get a BeginImplFrame by the normal mechanism, we // set the interval to twice the interval from the previous frame. advance_commit_state_task_.Reset(advance_commit_state_closure_); - task_runner_->PostDelayedTask(FROM_HERE, - advance_commit_state_task_.callback(), - begin_impl_frame_args_.interval * 2); + impl_task_runner_->PostDelayedTask(FROM_HERE, + advance_commit_state_task_.callback(), + begin_impl_frame_args_.interval * 2); } } else { advance_commit_state_task_.Cancel(); @@ -494,7 +491,7 @@ void Scheduler::PostBeginRetroFrameIfNeeded() { return; begin_retro_frame_posted_ = true; - task_runner_->PostTask(FROM_HERE, begin_retro_frame_closure_); + impl_task_runner_->PostTask(FROM_HERE, begin_retro_frame_closure_); } // BeginImplFrame starts a compositor frame that will wait up until a deadline @@ -502,8 +499,8 @@ void Scheduler::PostBeginRetroFrameIfNeeded() { // any asynchronous animation and scroll/pinch updates. void Scheduler::BeginImplFrame(const BeginFrameArgs& args) { TRACE_EVENT1("cc", "Scheduler::BeginImplFrame", "args", args.AsValue()); - DCHECK_EQ(state_machine_.begin_impl_frame_state(), - SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); + DCHECK(state_machine_.begin_impl_frame_state() == + SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); DCHECK(state_machine_.HasInitializedOutputSurface()); advance_commit_state_task_.Cancel(); @@ -570,7 +567,7 @@ void Scheduler::ScheduleBeginImplFrameDeadline(base::TimeTicks deadline) { base::TimeDelta delta = deadline - gfx::FrameTime::Now(); if (delta <= base::TimeDelta()) delta = base::TimeDelta(); - task_runner_->PostDelayedTask( + impl_task_runner_->PostDelayedTask( FROM_HERE, begin_impl_frame_deadline_task_.callback(), delta); } diff --git a/cc/scheduler/scheduler.h b/cc/scheduler/scheduler.h index ce3fed7..f6dd2bc 100644 --- a/cc/scheduler/scheduler.h +++ b/cc/scheduler/scheduler.h @@ -57,9 +57,9 @@ class CC_EXPORT Scheduler { SchedulerClient* client, const SchedulerSettings& scheduler_settings, int layer_tree_host_id, - const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) { + const scoped_refptr<base::SingleThreadTaskRunner>& impl_task_runner) { return make_scoped_ptr(new Scheduler( - client, scheduler_settings, layer_tree_host_id, task_runner)); + client, scheduler_settings, layer_tree_host_id, impl_task_runner)); } virtual ~Scheduler(); @@ -180,15 +180,16 @@ class CC_EXPORT Scheduler { scoped_refptr<DelayBasedTimeSource> time_source_; }; - Scheduler(SchedulerClient* client, - const SchedulerSettings& scheduler_settings, - int layer_tree_host_id, - const scoped_refptr<base::SingleThreadTaskRunner>& task_runner); + Scheduler( + SchedulerClient* client, + const SchedulerSettings& scheduler_settings, + int layer_tree_host_id, + const scoped_refptr<base::SingleThreadTaskRunner>& impl_task_runner); const SchedulerSettings settings_; SchedulerClient* client_; int layer_tree_host_id_; - scoped_refptr<base::SingleThreadTaskRunner> task_runner_; + scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner_; base::TimeDelta vsync_interval_; base::TimeDelta estimated_parent_draw_time_; diff --git a/cc/test/fake_layer_tree_host_client.h b/cc/test/fake_layer_tree_host_client.h index 7f7bd35..f928453 100644 --- a/cc/test/fake_layer_tree_host_client.h +++ b/cc/test/fake_layer_tree_host_client.h @@ -42,6 +42,8 @@ class FakeLayerTreeHostClient : public LayerTreeHostClient, virtual void DidCompleteSwapBuffers() OVERRIDE {} // LayerTreeHostSingleThreadClient implementation. + virtual void ScheduleComposite() OVERRIDE {} + virtual void ScheduleAnimation() OVERRIDE {} virtual void DidPostSwapBuffers() OVERRIDE {} virtual void DidAbortSwapBuffers() OVERRIDE {} diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc index b9d5063..0be1ed1 100644 --- a/cc/test/layer_tree_test.cc +++ b/cc/test/layer_tree_test.cc @@ -312,6 +312,14 @@ class LayerTreeHostClientForTesting : public LayerTreeHostClient, test_hooks_->DidCompleteSwapBuffers(); } + virtual void ScheduleComposite() OVERRIDE { + test_hooks_->ScheduleComposite(); + } + + virtual void ScheduleAnimation() OVERRIDE { + test_hooks_->ScheduleAnimation(); + } + virtual void DidPostSwapBuffers() OVERRIDE {} virtual void DidAbortSwapBuffers() OVERRIDE {} @@ -386,6 +394,7 @@ LayerTreeTest::LayerTreeTest() end_when_begin_returns_(false), timed_out_(false), scheduled_(false), + schedule_when_set_visible_true_(false), started_(false), ended_(false), delegating_renderer_(false), @@ -549,6 +558,15 @@ void LayerTreeTest::Timeout() { EndTest(); } +void LayerTreeTest::ScheduleComposite() { + if (!started_ || scheduled_) + return; + scheduled_ = true; + main_task_runner_->PostTask( + FROM_HERE, + base::Bind(&LayerTreeTest::DispatchComposite, main_thread_weak_ptr_)); +} + void LayerTreeTest::RealEndTest() { if (layer_tree_host_ && !timed_out_ && proxy()->MainFrameWillHappenForTesting()) { @@ -601,8 +619,16 @@ void LayerTreeTest::DispatchSetNeedsRedrawRect(const gfx::Rect& damage_rect) { void LayerTreeTest::DispatchSetVisible(bool visible) { DCHECK(!proxy() || proxy()->IsMainThread()); - if (layer_tree_host_) - layer_tree_host_->SetVisible(visible); + + if (!layer_tree_host_) + return; + + layer_tree_host_->SetVisible(visible); + + // If the LTH is being made visible and a previous ScheduleComposite() was + // deferred because the LTH was not visible, re-schedule the composite now. + if (layer_tree_host_->visible() && schedule_when_set_visible_true_) + ScheduleComposite(); } void LayerTreeTest::DispatchSetNextCommitForcesRedraw() { @@ -612,6 +638,24 @@ void LayerTreeTest::DispatchSetNextCommitForcesRedraw() { layer_tree_host_->SetNextCommitForcesRedraw(); } +void LayerTreeTest::DispatchComposite() { + scheduled_ = false; + + if (!layer_tree_host_) + return; + + // If the LTH is not visible, defer the composite until the LTH is made + // visible. + if (!layer_tree_host_->visible()) { + schedule_when_set_visible_true_ = true; + return; + } + + schedule_when_set_visible_true_ = false; + base::TimeTicks now = gfx::FrameTime::Now(); + layer_tree_host_->Composite(now); +} + void LayerTreeTest::RunTest(bool threaded, bool delegating_renderer, bool impl_side_painting) { diff --git a/cc/test/layer_tree_test.h b/cc/test/layer_tree_test.h index 619ae96..8f38dda 100644 --- a/cc/test/layer_tree_test.h +++ b/cc/test/layer_tree_test.h @@ -71,6 +71,8 @@ class TestHooks : public AnimationDelegate { virtual void DidCommit() {} virtual void DidCommitAndDrawFrame() {} virtual void DidCompleteSwapBuffers() {} + virtual void ScheduleComposite() {} + virtual void ScheduleAnimation() {} virtual void DidDeferCommit() {} virtual void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl, bool visible) {} @@ -137,6 +139,8 @@ class LayerTreeTest : public testing::Test, public TestHooks { virtual void InitializeSettings(LayerTreeSettings* settings) {} + virtual void ScheduleComposite() OVERRIDE; + void RealEndTest(); virtual void DispatchAddAnimation(Layer* layer_to_receive_animation, @@ -147,6 +151,7 @@ class LayerTreeTest : public testing::Test, public TestHooks { void DispatchSetNeedsRedrawRect(const gfx::Rect& damage_rect); void DispatchSetVisible(bool visible); void DispatchSetNextCommitForcesRedraw(); + void DispatchComposite(); void DispatchDidAddAnimation(); virtual void AfterTest() = 0; @@ -199,6 +204,7 @@ class LayerTreeTest : public testing::Test, public TestHooks { bool end_when_begin_returns_; bool timed_out_; bool scheduled_; + bool schedule_when_set_visible_true_; bool started_; bool ended_; bool delegating_renderer_; diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc index c43072f..6d9e236 100644 --- a/cc/trees/layer_tree_host.cc +++ b/cc/trees/layer_tree_host.cc @@ -697,12 +697,8 @@ void LayerTreeHost::NotifyInputThrottledUntilCommit() { void LayerTreeHost::Composite(base::TimeTicks frame_begin_time) { DCHECK(!proxy_->HasImplThread()); - // This function is only valid when not using the scheduler. - DCHECK(!settings_.single_thread_proxy_scheduler); SingleThreadProxy* proxy = static_cast<SingleThreadProxy*>(proxy_.get()); - SetLayerTreeHostClientReady(); - if (output_surface_lost_) proxy->CreateAndInitializeOutputSurface(); if (output_surface_lost_) diff --git a/cc/trees/layer_tree_host_perftest.cc b/cc/trees/layer_tree_host_perftest.cc index 4ddb1f2..70b2a64 100644 --- a/cc/trees/layer_tree_host_perftest.cc +++ b/cc/trees/layer_tree_host_perftest.cc @@ -228,8 +228,6 @@ class ScrollingLayerTreePerfTest : public LayerTreeHostPerfTestJsonReader { } virtual void Layout() OVERRIDE { - if (TestEnded()) - return; static const gfx::Vector2d delta = gfx::Vector2d(0, 10); scrollable_->SetScrollOffset(scrollable_->scroll_offset() + delta); } diff --git a/cc/trees/layer_tree_host_single_thread_client.h b/cc/trees/layer_tree_host_single_thread_client.h index dbca28c..cb61450 100644 --- a/cc/trees/layer_tree_host_single_thread_client.h +++ b/cc/trees/layer_tree_host_single_thread_client.h @@ -10,10 +10,10 @@ namespace cc { class LayerTreeHostSingleThreadClient { public: // Request that the client schedule a composite. - virtual void ScheduleComposite() {} + virtual void ScheduleComposite() = 0; // Request that the client schedule a composite now, and calculate appropriate // delay for potential future frame. - virtual void ScheduleAnimation() {} + virtual void ScheduleAnimation() = 0; // Called whenever the compositor posts a SwapBuffers (either full or // partial). After DidPostSwapBuffers(), exactly one of diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc index 9492884..0e72824 100644 --- a/cc/trees/layer_tree_host_unittest.cc +++ b/cc/trees/layer_tree_host_unittest.cc @@ -91,8 +91,8 @@ class LayerTreeHostTestSetNeedsCommit1 : public LayerTreeHostTest { } virtual void AfterTest() OVERRIDE { - EXPECT_LE(1, num_commits_); - EXPECT_LE(1, num_draws_); + EXPECT_GE(1, num_commits_); + EXPECT_GE(1, num_draws_); } private: @@ -694,6 +694,31 @@ class LayerTreeHostTestUndrawnLayersPushContentBoundsLater SINGLE_AND_MULTI_THREAD_TEST_F( LayerTreeHostTestUndrawnLayersPushContentBoundsLater); +class LayerTreeHostTestAbortFrameWhenInvisible : public LayerTreeHostTest { + public: + LayerTreeHostTestAbortFrameWhenInvisible() {} + + virtual void BeginTest() OVERRIDE { + // Request a commit (from the main thread), Which will trigger the commit + // flow from the impl side. + layer_tree_host()->SetNeedsCommit(); + // Then mark ourselves as not visible before processing any more messages + // on the main thread. + layer_tree_host()->SetVisible(false); + // If we make it without kicking a frame, we pass! + EndTestAfterDelay(1); + } + + virtual void Layout() OVERRIDE { + ASSERT_FALSE(true); + EndTest(); + } + + virtual void AfterTest() OVERRIDE {} +}; + +MULTI_THREAD_TEST_F(LayerTreeHostTestAbortFrameWhenInvisible); + // This test verifies that properties on the layer tree host are commited // to the impl side. class LayerTreeHostTestCommit : public LayerTreeHostTest { @@ -1893,7 +1918,7 @@ class LayerTreeHostTestDeferCommits : public LayerTreeHostTest { int num_complete_commits_; }; -SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestDeferCommits); +MULTI_THREAD_TEST_F(LayerTreeHostTestDeferCommits); class LayerTreeHostWithProxy : public LayerTreeHost { public: @@ -1966,7 +1991,6 @@ TEST(LayerTreeHostTest, PartialUpdatesWithGLRenderer) { LayerTreeSettings settings; settings.max_partial_texture_updates = 4; - settings.single_thread_proxy_scheduler = false; scoped_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); @@ -1986,7 +2010,6 @@ TEST(LayerTreeHostTest, PartialUpdatesWithSoftwareRenderer) { LayerTreeSettings settings; settings.max_partial_texture_updates = 4; - settings.single_thread_proxy_scheduler = false; scoped_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); @@ -2006,7 +2029,6 @@ TEST(LayerTreeHostTest, PartialUpdatesWithDelegatingRendererAndGLContent) { LayerTreeSettings settings; settings.max_partial_texture_updates = 4; - settings.single_thread_proxy_scheduler = false; scoped_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); @@ -2027,7 +2049,6 @@ TEST(LayerTreeHostTest, LayerTreeSettings settings; settings.max_partial_texture_updates = 4; - settings.single_thread_proxy_scheduler = false; scoped_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); @@ -4526,7 +4547,7 @@ class LayerTreeHostTestBreakSwapPromise : public LayerTreeHostTest { // TODO(miletus): Flaky test: crbug.com/393995 // MULTI_THREAD_TEST_F(LayerTreeHostTestBreakSwapPromise); -class LayerTreeHostTestBreakSwapPromiseForVisibilityAbortedCommit +class LayerTreeHostTestBreakSwapPromiseForAbortedCommit : public LayerTreeHostTest { protected: virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } @@ -4562,59 +4583,7 @@ class LayerTreeHostTestBreakSwapPromiseForVisibilityAbortedCommit TestSwapPromiseResult swap_promise_result_; }; -SINGLE_AND_MULTI_THREAD_TEST_F( - LayerTreeHostTestBreakSwapPromiseForVisibilityAbortedCommit); - -class LayerTreeHostTestBreakSwapPromiseForContextAbortedCommit - : public LayerTreeHostTest { - protected: - virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } - - virtual void DidCommit() OVERRIDE { - if (TestEnded()) - return; - layer_tree_host()->SetDeferCommits(true); - layer_tree_host()->SetNeedsCommit(); - } - - virtual void DidDeferCommit() OVERRIDE { - layer_tree_host()->DidLoseOutputSurface(); - scoped_ptr<SwapPromise> swap_promise( - new TestSwapPromise(&swap_promise_result_)); - layer_tree_host()->QueueSwapPromise(swap_promise.Pass()); - layer_tree_host()->SetDeferCommits(false); - } - - virtual void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl, - bool did_handle) OVERRIDE { - EndTest(); - // This lets the test finally commit and exit. - MainThreadTaskRunner()->PostTask( - FROM_HERE, - base::Bind(&LayerTreeHostTestBreakSwapPromiseForContextAbortedCommit:: - FindOutputSurface, - base::Unretained(this))); - } - - void FindOutputSurface() { - layer_tree_host()->OnCreateAndInitializeOutputSurfaceAttempted(true); - } - - virtual void AfterTest() OVERRIDE { - { - base::AutoLock lock(swap_promise_result_.lock); - EXPECT_FALSE(swap_promise_result_.did_swap_called); - EXPECT_TRUE(swap_promise_result_.did_not_swap_called); - EXPECT_EQ(SwapPromise::COMMIT_FAILS, swap_promise_result_.reason); - EXPECT_TRUE(swap_promise_result_.dtor_called); - } - } - - TestSwapPromiseResult swap_promise_result_; -}; - -SINGLE_AND_MULTI_THREAD_TEST_F( - LayerTreeHostTestBreakSwapPromiseForContextAbortedCommit); +MULTI_THREAD_TEST_F(LayerTreeHostTestBreakSwapPromiseForAbortedCommit); class SimpleSwapPromiseMonitor : public SwapPromiseMonitor { public: @@ -4699,7 +4668,7 @@ class LayerTreeHostTestSimpleSwapPromiseMonitor : public LayerTreeHostTest { virtual void AfterTest() OVERRIDE {} }; -SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSimpleSwapPromiseMonitor); +MULTI_THREAD_TEST_F(LayerTreeHostTestSimpleSwapPromiseMonitor); class LayerTreeHostTestHighResRequiredAfterEvictingUIResources : public LayerTreeHostTest { diff --git a/cc/trees/layer_tree_host_unittest_context.cc b/cc/trees/layer_tree_host_unittest_context.cc index 887e603..8fd9743 100644 --- a/cc/trees/layer_tree_host_unittest_context.cc +++ b/cc/trees/layer_tree_host_unittest_context.cc @@ -65,9 +65,6 @@ class LayerTreeHostContextTest : public LayerTreeTest { } void LoseContext() { - // For sanity-checking tests, they should only call this when the - // context is not lost. - CHECK(context3d_); context3d_->loseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB); context3d_ = NULL; @@ -311,8 +308,7 @@ class LayerTreeHostClientNotReadyDoesNotCreateOutputSurface } }; -SINGLE_AND_MULTI_THREAD_TEST_F( - LayerTreeHostClientNotReadyDoesNotCreateOutputSurface); +MULTI_THREAD_TEST_F(LayerTreeHostClientNotReadyDoesNotCreateOutputSurface); class LayerTreeHostContextTestLostContextSucceedsWithContent : public LayerTreeHostContextTestLostContextSucceeds { @@ -370,11 +366,10 @@ class LayerTreeHostContextTestCreateOutputSurfaceFails : times_to_fail_(times_to_fail), expect_fallback_attempt_(expect_fallback_attempt), did_attempt_fallback_(false), - times_initialized_(0) { - times_to_fail_create_ = times_to_fail_; - } + times_initialized_(0) {} virtual void BeginTest() OVERRIDE { + times_to_fail_create_ = times_to_fail_; PostSetNeedsCommitToMainThread(); } @@ -988,6 +983,12 @@ class ScrollbarLayerLostContext : public LayerTreeHostContextTest { EXPECT_EQ(2, scrollbar_layer_->update_count()); EndTest(); break; + case 3: + // Single thread proxy issues extra commits after context lost. + // http://crbug.com/287250 + if (HasImplThread()) + NOTREACHED(); + break; default: NOTREACHED(); } @@ -1031,10 +1032,12 @@ class UIResourceLostTest : public LayerTreeHostContextTest { void PostLoseContextToImplThread() { EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread()); - ImplThreadTaskRunner()->PostTask( - FROM_HERE, - base::Bind(&LayerTreeHostContextTest::LoseContext, - base::Unretained(this))); + base::SingleThreadTaskRunner* task_runner = + HasImplThread() ? ImplThreadTaskRunner() + : base::MessageLoopProxy::current(); + task_runner->PostTask(FROM_HERE, + base::Bind(&LayerTreeHostContextTest::LoseContext, + base::Unretained(this))); } protected: @@ -1089,8 +1092,13 @@ class UIResourceLostAfterCommit : public UIResourceLostTestSimple { EndTest(); break; case 5: - NOTREACHED(); + // Single thread proxy issues extra commits after context lost. + // http://crbug.com/287250 + if (HasImplThread()) + NOTREACHED(); break; + case 6: + NOTREACHED(); } } @@ -1178,8 +1186,13 @@ class UIResourceLostBeforeCommit : public UIResourceLostTestSimple { EndTest(); break; case 6: - NOTREACHED(); + // Single thread proxy issues extra commits after context lost. + // http://crbug.com/287250 + if (HasImplThread()) + NOTREACHED(); break; + case 8: + NOTREACHED(); } } @@ -1200,8 +1213,15 @@ class UIResourceLostBeforeCommit : public UIResourceLostTestSimple { // Sequence 2 (continued): // The previous resource should have been deleted. EXPECT_EQ(0u, impl->ResourceIdForUIResource(test_id0_)); - // The second resource should have been created. - EXPECT_NE(0u, impl->ResourceIdForUIResource(test_id1_)); + if (HasImplThread()) { + // The second resource should have been created. + EXPECT_NE(0u, impl->ResourceIdForUIResource(test_id1_)); + } else { + // The extra commit that happens at context lost in the single thread + // proxy changes the timing so that the resource has been destroyed. + // http://crbug.com/287250 + EXPECT_EQ(0u, impl->ResourceIdForUIResource(test_id1_)); + } // The second resource called the resource callback once and since the // context is lost, a "resource lost" callback was also issued. EXPECT_EQ(2, ui_resource_->resource_create_count); @@ -1517,8 +1537,8 @@ class LayerTreeHostContextTestLoseAfterSendingBeginMainFrame bool deferred_; }; -SINGLE_AND_MULTI_THREAD_TEST_F( - LayerTreeHostContextTestLoseAfterSendingBeginMainFrame); +// TODO(danakj): We don't use scheduler with SingleThreadProxy yet. +MULTI_THREAD_TEST_F(LayerTreeHostContextTestLoseAfterSendingBeginMainFrame); } // namespace } // namespace cc diff --git a/cc/trees/layer_tree_host_unittest_no_message_loop.cc b/cc/trees/layer_tree_host_unittest_no_message_loop.cc index ea3bfc6..1a24ba5 100644 --- a/cc/trees/layer_tree_host_unittest_no_message_loop.cc +++ b/cc/trees/layer_tree_host_unittest_no_message_loop.cc @@ -74,6 +74,8 @@ class LayerTreeHostNoMessageLoopTest virtual void DidCompleteSwapBuffers() OVERRIDE {} // LayerTreeHostSingleThreadClient overrides. + virtual void ScheduleComposite() OVERRIDE {} + virtual void ScheduleAnimation() OVERRIDE {} virtual void DidPostSwapBuffers() OVERRIDE {} virtual void DidAbortSwapBuffers() OVERRIDE {} @@ -94,7 +96,6 @@ class LayerTreeHostNoMessageLoopTest void SetupLayerTreeHost() { LayerTreeSettings settings; - settings.single_thread_proxy_scheduler = false; layer_tree_host_ = LayerTreeHost::CreateSingleThreaded(this, this, NULL, settings, NULL); layer_tree_host_->SetViewportSize(size_); diff --git a/cc/trees/layer_tree_settings.cc b/cc/trees/layer_tree_settings.cc index 56e18a2..bf72893 100644 --- a/cc/trees/layer_tree_settings.cc +++ b/cc/trees/layer_tree_settings.cc @@ -16,7 +16,6 @@ LayerTreeSettings::LayerTreeSettings() : impl_side_painting(false), allow_antialiasing(true), throttle_frame_production(true), - single_thread_proxy_scheduler(true), begin_frame_scheduling_enabled(false), main_frame_before_draw_enabled(true), main_frame_before_activation_enabled(false), diff --git a/cc/trees/layer_tree_settings.h b/cc/trees/layer_tree_settings.h index bad3bf4..14cec67 100644 --- a/cc/trees/layer_tree_settings.h +++ b/cc/trees/layer_tree_settings.h @@ -21,7 +21,6 @@ class CC_EXPORT LayerTreeSettings { bool impl_side_painting; bool allow_antialiasing; bool throttle_frame_production; - bool single_thread_proxy_scheduler; bool begin_frame_scheduling_enabled; bool main_frame_before_draw_enabled; bool main_frame_before_activation_enabled; diff --git a/cc/trees/scoped_abort_remaining_swap_promises.h b/cc/trees/scoped_abort_remaining_swap_promises.h deleted file mode 100644 index f8dfc01..0000000 --- a/cc/trees/scoped_abort_remaining_swap_promises.h +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2014 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_SCOPED_ABORT_REMAINING_SWAP_PROMISES_H_ -#define CC_TREES_SCOPED_ABORT_REMAINING_SWAP_PROMISES_H_ - -#include "cc/base/swap_promise.h" -#include "cc/trees/layer_tree_host.h" - -namespace cc { - -class ScopedAbortRemainingSwapPromises { - public: - explicit ScopedAbortRemainingSwapPromises(LayerTreeHost* layer_tree_host) - : layer_tree_host_(layer_tree_host) {} - - ~ScopedAbortRemainingSwapPromises() { - layer_tree_host_->BreakSwapPromises(SwapPromise::COMMIT_FAILS); - } - - private: - LayerTreeHost* layer_tree_host_; - - DISALLOW_COPY_AND_ASSIGN(ScopedAbortRemainingSwapPromises); -}; - -} // namespace cc - -#endif // CC_TREES_SCOPED_ABORT_REMAINING_SWAP_PROMISES_H_ diff --git a/cc/trees/single_thread_proxy.cc b/cc/trees/single_thread_proxy.cc index 7be4ca8..f400733 100644 --- a/cc/trees/single_thread_proxy.cc +++ b/cc/trees/single_thread_proxy.cc @@ -16,7 +16,6 @@ #include "cc/trees/layer_tree_host.h" #include "cc/trees/layer_tree_host_single_thread_client.h" #include "cc/trees/layer_tree_impl.h" -#include "cc/trees/scoped_abort_remaining_swap_promises.h" #include "ui/gfx/frame_time.h" namespace cc { @@ -37,13 +36,8 @@ SingleThreadProxy::SingleThreadProxy( : Proxy(main_task_runner, NULL), layer_tree_host_(layer_tree_host), client_(client), - timing_history_(layer_tree_host->rendering_stats_instrumentation()), next_frame_is_newly_committed_frame_(false), - inside_draw_(false), - defer_commits_(false), - commit_was_deferred_(false), - commit_requested_(false), - weak_factory_(this) { + inside_draw_(false) { TRACE_EVENT0("cc", "SingleThreadProxy::SingleThreadProxy"); DCHECK(Proxy::IsMainThread()); DCHECK(layer_tree_host); @@ -83,26 +77,13 @@ void SingleThreadProxy::SetLayerTreeHostClientReady() { TRACE_EVENT0("cc", "SingleThreadProxy::SetLayerTreeHostClientReady"); // Scheduling is controlled by the embedder in the single thread case, so // nothing to do. - DCHECK(Proxy::IsMainThread()); - DebugScopedSetImplThread impl(this); - if (layer_tree_host_->settings().single_thread_proxy_scheduler && - !scheduler_on_impl_thread_) { - SchedulerSettings scheduler_settings(layer_tree_host_->settings()); - scheduler_on_impl_thread_ = Scheduler::Create(this, - scheduler_settings, - layer_tree_host_->id(), - MainThreadTaskRunner()); - scheduler_on_impl_thread_->SetCanStart(); - scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible()); - } } void SingleThreadProxy::SetVisible(bool visible) { TRACE_EVENT0("cc", "SingleThreadProxy::SetVisible"); DebugScopedSetImplThread impl(this); layer_tree_host_impl_->SetVisible(visible); - if (scheduler_on_impl_thread_) - scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible()); + // Changing visibility could change ShouldComposite(). UpdateBackgroundAnimateTicking(); } @@ -129,14 +110,9 @@ void SingleThreadProxy::CreateAndInitializeOutputSurface() { layer_tree_host_->OnCreateAndInitializeOutputSurfaceAttempted(success); - if (success) { - if (scheduler_on_impl_thread_) - scheduler_on_impl_thread_->DidCreateAndInitializeOutputSurface(); - } else if (Proxy::MainThreadTaskRunner()) { - MainThreadTaskRunner()->PostTask( - FROM_HERE, - base::Bind(&SingleThreadProxy::CreateAndInitializeOutputSurface, - weak_factory_.GetWeakPtr())); + if (!success) { + // Force another recreation attempt to happen by requesting another commit. + SetNeedsCommit(); } } @@ -150,40 +126,17 @@ void SingleThreadProxy::SetNeedsAnimate() { TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsAnimate"); DCHECK(Proxy::IsMainThread()); client_->ScheduleAnimation(); - SetNeedsCommit(); } void SingleThreadProxy::SetNeedsUpdateLayers() { TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsUpdateLayers"); DCHECK(Proxy::IsMainThread()); - SetNeedsCommit(); + client_->ScheduleComposite(); } -void SingleThreadProxy::DoCommit(base::TimeTicks frame_begin_time) { +void SingleThreadProxy::DoCommit(scoped_ptr<ResourceUpdateQueue> queue) { TRACE_EVENT0("cc", "SingleThreadProxy::DoCommit"); DCHECK(Proxy::IsMainThread()); - layer_tree_host_->WillBeginMainFrame(); - layer_tree_host_->UpdateClientAnimations(frame_begin_time); - layer_tree_host_->AnimateLayers(frame_begin_time); - layer_tree_host_->Layout(); - commit_requested_ = false; - - if (PrioritizedResourceManager* contents_texture_manager = - layer_tree_host_->contents_texture_manager()) { - contents_texture_manager->UnlinkAndClearEvictedBackings(); - contents_texture_manager->SetMaxMemoryLimitBytes( - layer_tree_host_impl_->memory_allocation_limit_bytes()); - contents_texture_manager->SetExternalPriorityCutoff( - layer_tree_host_impl_->memory_allocation_priority_cutoff()); - } - - scoped_ptr<ResourceUpdateQueue> queue = - make_scoped_ptr(new ResourceUpdateQueue); - - layer_tree_host_->UpdateLayers(queue.get()); - - layer_tree_host_->WillCommit(); - // Commit immediately. { DebugScopedSetMainThreadBlocked main_thread_blocked(this); @@ -205,7 +158,7 @@ void SingleThreadProxy::DoCommit(base::TimeTicks frame_begin_time) { scoped_ptr<ResourceUpdateController> update_controller = ResourceUpdateController::Create( NULL, - MainThreadTaskRunner(), + Proxy::MainThreadTaskRunner(), queue.Pass(), layer_tree_host_impl_->resource_provider()); update_controller->Finalize(); @@ -217,8 +170,6 @@ void SingleThreadProxy::DoCommit(base::TimeTicks frame_begin_time) { layer_tree_host_impl_->CommitComplete(); - UpdateBackgroundAnimateTicking(); - #if DCHECK_IS_ON // In the single-threaded case, the scale and scroll deltas should never be // touched on the impl layer tree. @@ -235,62 +186,33 @@ void SingleThreadProxy::DoCommit(base::TimeTicks frame_begin_time) { stats_instrumentation->AccumulateAndClearMainThreadStats(); } layer_tree_host_->CommitComplete(); - layer_tree_host_->DidBeginMainFrame(); - timing_history_.DidCommit(); - next_frame_is_newly_committed_frame_ = true; } void SingleThreadProxy::SetNeedsCommit() { DCHECK(Proxy::IsMainThread()); - DebugScopedSetImplThread impl(this); client_->ScheduleComposite(); - if (scheduler_on_impl_thread_) - scheduler_on_impl_thread_->SetNeedsCommit(); - commit_requested_ = true; } void SingleThreadProxy::SetNeedsRedraw(const gfx::Rect& damage_rect) { TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsRedraw"); - DCHECK(Proxy::IsMainThread()); - DebugScopedSetImplThread impl(this); - client_->ScheduleComposite(); SetNeedsRedrawRectOnImplThread(damage_rect); + client_->ScheduleComposite(); } void SingleThreadProxy::SetNextCommitWaitsForActivation() { // There is no activation here other than commit. So do nothing. - DCHECK(Proxy::IsMainThread()); } void SingleThreadProxy::SetDeferCommits(bool defer_commits) { - DCHECK(Proxy::IsMainThread()); - // Deferring commits only makes sense if there's a scheduler. - if (!scheduler_on_impl_thread_) - return; - if (defer_commits_ == defer_commits) - return; - - if (defer_commits) - TRACE_EVENT_ASYNC_BEGIN0("cc", "SingleThreadProxy::SetDeferCommits", this); - else - TRACE_EVENT_ASYNC_END0("cc", "SingleThreadProxy::SetDeferCommits", this); - - defer_commits_ = defer_commits; - if (!defer_commits_ && commit_was_deferred_) { - commit_was_deferred_ = false; - BeginMainFrame(); - } } bool SingleThreadProxy::CommitRequested() const { - DCHECK(Proxy::IsMainThread()); - return commit_requested_; + return false; } bool SingleThreadProxy::BeginMainFrameRequested() const { - DCHECK(Proxy::IsMainThread()); - return commit_requested_; + return false; } size_t SingleThreadProxy::MaxPartialTextureUpdates() const { @@ -307,7 +229,6 @@ void SingleThreadProxy::Stop() { BlockingTaskRunner::CapturePostTasks blocked; layer_tree_host_->DeleteContentsTexturesOnImplThread( layer_tree_host_impl_->resource_provider()); - scheduler_on_impl_thread_.reset(); layer_tree_host_impl_.reset(); } layer_tree_host_ = NULL; @@ -318,19 +239,15 @@ void SingleThreadProxy::OnCanDrawStateChanged(bool can_draw) { "cc", "SingleThreadProxy::OnCanDrawStateChanged", "can_draw", can_draw); DCHECK(Proxy::IsImplThread()); UpdateBackgroundAnimateTicking(); - if (scheduler_on_impl_thread_) - scheduler_on_impl_thread_->SetCanDraw(can_draw); } void SingleThreadProxy::NotifyReadyToActivate() { - // Impl-side painting only. + // Thread-only feature. NOTREACHED(); } void SingleThreadProxy::SetNeedsRedrawOnImplThread() { client_->ScheduleComposite(); - if (scheduler_on_impl_thread_) - scheduler_on_impl_thread_->SetNeedsRedraw(); } void SingleThreadProxy::SetNeedsAnimateOnImplThread() { @@ -338,14 +255,17 @@ void SingleThreadProxy::SetNeedsAnimateOnImplThread() { } void SingleThreadProxy::SetNeedsManageTilesOnImplThread() { - // Impl-side painting only. + // Thread-only/Impl-side-painting-only feature. NOTREACHED(); } void SingleThreadProxy::SetNeedsRedrawRectOnImplThread( const gfx::Rect& damage_rect) { + // TODO(brianderson): Once we move render_widget scheduling into this class, + // we can treat redraw requests more efficiently than CommitAndRedraw + // requests. layer_tree_host_impl_->SetViewportDamage(damage_rect); - SetNeedsRedrawOnImplThread(); + SetNeedsCommit(); } void SingleThreadProxy::DidInitializeVisibleTileOnImplThread() { @@ -355,8 +275,6 @@ void SingleThreadProxy::DidInitializeVisibleTileOnImplThread() { void SingleThreadProxy::SetNeedsCommitOnImplThread() { client_->ScheduleComposite(); - if (scheduler_on_impl_thread_) - scheduler_on_impl_thread_->SetNeedsCommit(); } void SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread( @@ -393,53 +311,66 @@ void SingleThreadProxy::UpdateRendererCapabilitiesOnImplThread() { layer_tree_host_impl_->GetRendererCapabilities().MainThreadCapabilities(); } -void SingleThreadProxy::DidManageTiles() { - // Impl-side painting only. - NOTREACHED(); -} - void SingleThreadProxy::DidLoseOutputSurfaceOnImplThread() { TRACE_EVENT0("cc", "SingleThreadProxy::DidLoseOutputSurfaceOnImplThread"); - { - DebugScopedSetMainThread main(this); - // This must happen before we notify the scheduler as it may try to recreate - // the output surface if already in BEGIN_IMPL_FRAME_STATE_IDLE. - layer_tree_host_->DidLoseOutputSurface(); - } + // Cause a commit so we can notice the lost context. + SetNeedsCommitOnImplThread(); client_->DidAbortSwapBuffers(); - if (scheduler_on_impl_thread_) - scheduler_on_impl_thread_->DidLoseOutputSurface(); } void SingleThreadProxy::DidSwapBuffersOnImplThread() { - TRACE_EVENT0("cc", "SingleThreadProxy::DidSwapBuffersOnImplThread"); - if (scheduler_on_impl_thread_) - scheduler_on_impl_thread_->DidSwapBuffers(); client_->DidPostSwapBuffers(); } void SingleThreadProxy::DidSwapBuffersCompleteOnImplThread() { TRACE_EVENT0("cc", "SingleThreadProxy::DidSwapBuffersCompleteOnImplThread"); - if (scheduler_on_impl_thread_) - scheduler_on_impl_thread_->DidSwapBuffersComplete(); - layer_tree_host_->DidCompleteSwapBuffers(); -} - -void SingleThreadProxy::BeginFrame(const BeginFrameArgs& args) { - TRACE_EVENT0("cc", "SingleThreadProxy::BeginFrame"); - if (scheduler_on_impl_thread_) - scheduler_on_impl_thread_->BeginImplFrame(args); + client_->DidCompleteSwapBuffers(); } +// Called by the legacy scheduling path (e.g. where render_widget does the +// scheduling) void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time) { TRACE_EVENT0("cc", "SingleThreadProxy::CompositeImmediately"); DCHECK(Proxy::IsMainThread()); DCHECK(!layer_tree_host_->output_surface_lost()); - DoCommit(frame_begin_time); + layer_tree_host_->AnimateLayers(frame_begin_time); + + if (PrioritizedResourceManager* contents_texture_manager = + layer_tree_host_->contents_texture_manager()) { + contents_texture_manager->UnlinkAndClearEvictedBackings(); + contents_texture_manager->SetMaxMemoryLimitBytes( + layer_tree_host_impl_->memory_allocation_limit_bytes()); + contents_texture_manager->SetExternalPriorityCutoff( + layer_tree_host_impl_->memory_allocation_priority_cutoff()); + } + + scoped_ptr<ResourceUpdateQueue> queue = + make_scoped_ptr(new ResourceUpdateQueue); + layer_tree_host_->UpdateLayers(queue.get()); + layer_tree_host_->WillCommit(); + DoCommit(queue.Pass()); + layer_tree_host_->DidBeginMainFrame(); LayerTreeHostImpl::FrameData frame; - DoComposite(frame_begin_time, &frame); + if (DoComposite(frame_begin_time, &frame)) { + { + DebugScopedSetMainThreadBlocked main_thread_blocked(this); + DebugScopedSetImplThread impl(this); + + // This CapturePostTasks should be destroyed before + // DidCommitAndDrawFrame() is called since that goes out to the embedder, + // and we want the embedder to receive its callbacks before that. + // NOTE: This maintains consistent ordering with the ThreadProxy since + // the DidCommitAndDrawFrame() must be post-tasked from the impl thread + // there as the main thread is not blocked, so any posted tasks inside + // the swap buffers will execute first. + BlockingTaskRunner::CapturePostTasks blocked; + + layer_tree_host_impl_->SwapBuffers(frame); + } + DidSwapFrame(); + } } void SingleThreadProxy::AsValueInto(base::debug::TracedValue* state) const { @@ -479,11 +410,12 @@ void SingleThreadProxy::UpdateBackgroundAnimateTicking() { !ShouldComposite() && layer_tree_host_impl_->active_tree()->root_layer()); } -DrawResult SingleThreadProxy::DoComposite(base::TimeTicks frame_begin_time, - LayerTreeHostImpl::FrameData* frame) { +bool SingleThreadProxy::DoComposite(base::TimeTicks frame_begin_time, + LayerTreeHostImpl::FrameData* frame) { TRACE_EVENT0("cc", "SingleThreadProxy::DoComposite"); DCHECK(!layer_tree_host_->output_surface_lost()); + bool lost_output_surface = false; { DebugScopedSetImplThread impl(this); base::AutoReset<bool> mark_inside(&inside_draw_, true); @@ -494,11 +426,9 @@ DrawResult SingleThreadProxy::DoComposite(base::TimeTicks frame_begin_time, // CanDraw() as well. if (!ShouldComposite()) { UpdateBackgroundAnimateTicking(); - return DRAW_ABORTED_CANT_DRAW; + return false; } - timing_history_.DidStartDrawing(); - layer_tree_host_impl_->Animate( layer_tree_host_impl_->CurrentFrameTimeTicks()); UpdateBackgroundAnimateTicking(); @@ -508,43 +438,24 @@ DrawResult SingleThreadProxy::DoComposite(base::TimeTicks frame_begin_time, layer_tree_host_impl_->DrawLayers(frame, frame_begin_time); layer_tree_host_impl_->DidDrawAllLayers(*frame); } + lost_output_surface = layer_tree_host_impl_->IsContextLost(); bool start_ready_animations = true; layer_tree_host_impl_->UpdateAnimationState(start_ready_animations); layer_tree_host_impl_->ResetCurrentFrameTimeForNextFrame(); - - timing_history_.DidFinishDrawing(); } - { - DebugScopedSetImplThread impl(this); - - if (layer_tree_host_impl_->IsContextLost()) { - DidLoseOutputSurfaceOnImplThread(); - } else { - // This CapturePostTasks should be destroyed before - // DidCommitAndDrawFrame() is called since that goes out to the - // embedder, - // and we want the embedder to receive its callbacks before that. - // NOTE: This maintains consistent ordering with the ThreadProxy since - // the DidCommitAndDrawFrame() must be post-tasked from the impl thread - // there as the main thread is not blocked, so any posted tasks inside - // the swap buffers will execute first. - DebugScopedSetMainThreadBlocked main_thread_blocked(this); - - BlockingTaskRunner::CapturePostTasks blocked; - layer_tree_host_impl_->SwapBuffers(*frame); - } + if (lost_output_surface) { + layer_tree_host_->DidLoseOutputSurface(); + return false; } - DidCommitAndDrawFrame(); - return DRAW_SUCCESS; + return true; } -void SingleThreadProxy::DidCommitAndDrawFrame() { +void SingleThreadProxy::DidSwapFrame() { if (next_frame_is_newly_committed_frame_) { - DebugScopedSetMainThread main(this); next_frame_is_newly_committed_frame_ = false; layer_tree_host_->DidCommitAndDrawFrame(); } @@ -554,146 +465,4 @@ bool SingleThreadProxy::MainFrameWillHappenForTesting() { return false; } -void SingleThreadProxy::SetNeedsBeginFrame(bool enable) { - layer_tree_host_impl_->SetNeedsBeginFrame(enable); -} - -void SingleThreadProxy::WillBeginImplFrame(const BeginFrameArgs& args) { - layer_tree_host_impl_->WillBeginImplFrame(args); -} - -void SingleThreadProxy::ScheduledActionSendBeginMainFrame() { - TRACE_EVENT0("cc", "SingleThreadProxy::ScheduledActionSendBeginMainFrame"); - // Although this proxy is single-threaded, it's problematic to synchronously - // have BeginMainFrame happen after ScheduledActionSendBeginMainFrame. This - // could cause a commit to occur in between a series of SetNeedsCommit calls - // (i.e. property modifications) causing some to fall on one frame and some to - // fall on the next. Doing it asynchronously instead matches the semantics of - // ThreadProxy::SetNeedsCommit where SetNeedsCommit will not cause a - // synchronous commit. - MainThreadTaskRunner()->PostTask( - FROM_HERE, - base::Bind(&SingleThreadProxy::BeginMainFrame, - weak_factory_.GetWeakPtr())); -} - -void SingleThreadProxy::BeginMainFrame() { - if (defer_commits_) { - DCHECK(!commit_was_deferred_); - commit_was_deferred_ = true; - layer_tree_host_->DidDeferCommit(); - return; - } - - // This checker assumes NotifyReadyToCommit below causes a synchronous commit. - ScopedAbortRemainingSwapPromises swap_promise_checker(layer_tree_host_); - - if (!layer_tree_host_->visible()) { - TRACE_EVENT_INSTANT0("cc", "EarlyOut_NotVisible", TRACE_EVENT_SCOPE_THREAD); - BeginMainFrameAbortedOnImplThread(); - return; - } - - if (layer_tree_host_->output_surface_lost()) { - TRACE_EVENT_INSTANT0( - "cc", "EarlyOut_OutputSurfaceLost", TRACE_EVENT_SCOPE_THREAD); - BeginMainFrameAbortedOnImplThread(); - return; - } - - timing_history_.DidBeginMainFrame(); - - DCHECK(scheduler_on_impl_thread_); - scheduler_on_impl_thread_->NotifyBeginMainFrameStarted(); - scheduler_on_impl_thread_->NotifyReadyToCommit(); -} - -void SingleThreadProxy::BeginMainFrameAbortedOnImplThread() { - DebugScopedSetImplThread impl(this); - DCHECK(scheduler_on_impl_thread_->CommitPending()); - DCHECK(!layer_tree_host_impl_->pending_tree()); - - // TODO(enne): SingleThreadProxy does not support cancelling commits yet so - // did_handle is always false. - bool did_handle = false; - layer_tree_host_impl_->BeginMainFrameAborted(did_handle); - scheduler_on_impl_thread_->BeginMainFrameAborted(did_handle); -} - -DrawResult SingleThreadProxy::ScheduledActionDrawAndSwapIfPossible() { - DebugScopedSetImplThread impl(this); - if (layer_tree_host_impl_->IsContextLost()) { - DidCommitAndDrawFrame(); - return DRAW_SUCCESS; - } - - LayerTreeHostImpl::FrameData frame; - return DoComposite(layer_tree_host_impl_->CurrentFrameTimeTicks(), &frame); -} - -DrawResult SingleThreadProxy::ScheduledActionDrawAndSwapForced() { - NOTREACHED(); - return INVALID_RESULT; -} - -void SingleThreadProxy::ScheduledActionCommit() { - DebugScopedSetMainThread main(this); - DoCommit(layer_tree_host_impl_->CurrentFrameTimeTicks()); -} - -void SingleThreadProxy::ScheduledActionAnimate() { - TRACE_EVENT0("cc", "ScheduledActionAnimate"); - layer_tree_host_impl_->Animate( - layer_tree_host_impl_->CurrentFrameTimeTicks()); -} - -void SingleThreadProxy::ScheduledActionUpdateVisibleTiles() { - // Impl-side painting only. - NOTREACHED(); -} - -void SingleThreadProxy::ScheduledActionActivateSyncTree() { -} - -void SingleThreadProxy::ScheduledActionBeginOutputSurfaceCreation() { - DebugScopedSetMainThread main(this); - DCHECK(scheduler_on_impl_thread_); - // If possible, create the output surface in a post task. Synchronously - // creating the output surface makes tests more awkward since this differs - // from the ThreadProxy behavior. However, sometimes there is no - // task runner. - if (Proxy::MainThreadTaskRunner()) { - MainThreadTaskRunner()->PostTask( - FROM_HERE, - base::Bind(&SingleThreadProxy::CreateAndInitializeOutputSurface, - weak_factory_.GetWeakPtr())); - } else { - CreateAndInitializeOutputSurface(); - } -} - -void SingleThreadProxy::ScheduledActionManageTiles() { - // Impl-side painting only. - NOTREACHED(); -} - -void SingleThreadProxy::DidAnticipatedDrawTimeChange(base::TimeTicks time) { -} - -base::TimeDelta SingleThreadProxy::DrawDurationEstimate() { - return timing_history_.DrawDurationEstimate(); -} - -base::TimeDelta SingleThreadProxy::BeginMainFrameToCommitDurationEstimate() { - return timing_history_.BeginMainFrameToCommitDurationEstimate(); -} - -base::TimeDelta SingleThreadProxy::CommitToActivateDurationEstimate() { - return timing_history_.CommitToActivateDurationEstimate(); -} - -void SingleThreadProxy::DidBeginImplFrameDeadline() { - layer_tree_host_impl_->ResetCurrentFrameTimeForNextFrame(); -} - } // namespace cc diff --git a/cc/trees/single_thread_proxy.h b/cc/trees/single_thread_proxy.h index d06c54b..685b11a 100644 --- a/cc/trees/single_thread_proxy.h +++ b/cc/trees/single_thread_proxy.h @@ -10,10 +10,8 @@ #include "base/time/time.h" #include "cc/animation/animation_events.h" #include "cc/output/begin_frame_args.h" -#include "cc/scheduler/scheduler.h" #include "cc/trees/layer_tree_host_impl.h" #include "cc/trees/proxy.h" -#include "cc/trees/proxy_timing_history.h" namespace cc { @@ -22,8 +20,7 @@ class LayerTreeHost; class LayerTreeHostSingleThreadClient; class CC_EXPORT SingleThreadProxy : public Proxy, - NON_EXPORTED_BASE(LayerTreeHostImplClient), - SchedulerClient { + NON_EXPORTED_BASE(LayerTreeHostImplClient) { public: static scoped_ptr<Proxy> Create( LayerTreeHost* layer_tree_host, @@ -55,24 +52,6 @@ class CC_EXPORT SingleThreadProxy : public Proxy, virtual void AsValueInto(base::debug::TracedValue* state) const OVERRIDE; virtual bool MainFrameWillHappenForTesting() OVERRIDE; - // SchedulerClient implementation - virtual void SetNeedsBeginFrame(bool enable) OVERRIDE; - virtual void WillBeginImplFrame(const BeginFrameArgs& args) OVERRIDE; - virtual void ScheduledActionSendBeginMainFrame() OVERRIDE; - virtual DrawResult ScheduledActionDrawAndSwapIfPossible() OVERRIDE; - virtual DrawResult ScheduledActionDrawAndSwapForced() OVERRIDE; - virtual void ScheduledActionCommit() OVERRIDE; - virtual void ScheduledActionAnimate() OVERRIDE; - virtual void ScheduledActionUpdateVisibleTiles() OVERRIDE; - virtual void ScheduledActionActivateSyncTree() OVERRIDE; - virtual void ScheduledActionBeginOutputSurfaceCreation() OVERRIDE; - virtual void ScheduledActionManageTiles() OVERRIDE; - virtual void DidAnticipatedDrawTimeChange(base::TimeTicks time) OVERRIDE; - virtual base::TimeDelta DrawDurationEstimate() OVERRIDE; - virtual base::TimeDelta BeginMainFrameToCommitDurationEstimate() OVERRIDE; - virtual base::TimeDelta CommitToActivateDurationEstimate() OVERRIDE; - virtual void DidBeginImplFrameDeadline() OVERRIDE; - // LayerTreeHostImplClient implementation virtual void UpdateRendererCapabilitiesOnImplThread() OVERRIDE; virtual void DidLoseOutputSurfaceOnImplThread() OVERRIDE; @@ -82,7 +61,7 @@ class CC_EXPORT SingleThreadProxy : public Proxy, virtual void SetMaxSwapsPendingOnImplThread(int max) OVERRIDE {} virtual void DidSwapBuffersOnImplThread() OVERRIDE; virtual void DidSwapBuffersCompleteOnImplThread() OVERRIDE; - virtual void BeginFrame(const BeginFrameArgs& args) OVERRIDE; + virtual void BeginFrame(const BeginFrameArgs& args) OVERRIDE {} virtual void OnCanDrawStateChanged(bool can_draw) OVERRIDE; virtual void NotifyReadyToActivate() OVERRIDE; virtual void SetNeedsRedrawOnImplThread() OVERRIDE; @@ -103,7 +82,7 @@ class CC_EXPORT SingleThreadProxy : public Proxy, const base::Closure& start_fade, base::TimeDelta delay) OVERRIDE {} virtual void DidActivateSyncTree() OVERRIDE {} - virtual void DidManageTiles() OVERRIDE; + virtual void DidManageTiles() OVERRIDE {} virtual void SetDebugState(const LayerTreeDebugState& debug_state) OVERRIDE {} // Attempts to create the context and renderer synchronously. Calls @@ -119,13 +98,10 @@ class CC_EXPORT SingleThreadProxy : public Proxy, LayerTreeHostSingleThreadClient* client, scoped_refptr<base::SingleThreadTaskRunner> main_task_runner); - void BeginMainFrame(); - void BeginMainFrameAbortedOnImplThread(); - void DoCommit(base::TimeTicks frame_begin_time); - DrawResult DoComposite(base::TimeTicks frame_begin_time, - LayerTreeHostImpl::FrameData* frame); - void DoSwap(); - void DidCommitAndDrawFrame(); + void DoCommit(scoped_ptr<ResourceUpdateQueue> queue); + bool DoComposite(base::TimeTicks frame_begin_time, + LayerTreeHostImpl::FrameData* frame); + void DidSwapFrame(); bool ShouldComposite() const; void UpdateBackgroundAnimateTicking(); @@ -139,18 +115,9 @@ class CC_EXPORT SingleThreadProxy : public Proxy, scoped_ptr<LayerTreeHostImpl> layer_tree_host_impl_; RendererCapabilities renderer_capabilities_for_main_thread_; - // Accessed from both threads. - scoped_ptr<Scheduler> scheduler_on_impl_thread_; - ProxyTimingHistory timing_history_; - bool next_frame_is_newly_committed_frame_; bool inside_draw_; - bool defer_commits_; - bool commit_was_deferred_; - bool commit_requested_; - - base::WeakPtrFactory<SingleThreadProxy> weak_factory_; DISALLOW_COPY_AND_ASSIGN(SingleThreadProxy); }; diff --git a/cc/trees/thread_proxy.cc b/cc/trees/thread_proxy.cc index ac8b4fd..a4a630e 100644 --- a/cc/trees/thread_proxy.cc +++ b/cc/trees/thread_proxy.cc @@ -25,7 +25,6 @@ #include "cc/trees/blocking_task_runner.h" #include "cc/trees/layer_tree_host.h" #include "cc/trees/layer_tree_impl.h" -#include "cc/trees/scoped_abort_remaining_swap_promises.h" #include "gpu/command_buffer/client/gles2_interface.h" #include "ui/gfx/frame_time.h" @@ -38,6 +37,19 @@ const double kSmoothnessTakesPriorityExpirationDelay = 0.25; unsigned int nextBeginFrameId = 0; +class SwapPromiseChecker { + public: + explicit SwapPromiseChecker(LayerTreeHost* layer_tree_host) + : layer_tree_host_(layer_tree_host) {} + + ~SwapPromiseChecker() { + layer_tree_host_->BreakSwapPromises(SwapPromise::COMMIT_FAILS); + } + + private: + LayerTreeHost* layer_tree_host_; +}; + } // namespace struct ThreadProxy::SchedulerStateRequest { @@ -441,10 +453,9 @@ void ThreadProxy::SetNextCommitWaitsForActivation() { void ThreadProxy::SetDeferCommits(bool defer_commits) { DCHECK(IsMainThread()); - if (main().defer_commits == defer_commits) - return; - + DCHECK_NE(main().defer_commits, defer_commits); main().defer_commits = defer_commits; + if (main().defer_commits) TRACE_EVENT_ASYNC_BEGIN0("cc", "ThreadProxy::SetDeferCommits", this); else @@ -724,9 +735,9 @@ void ThreadProxy::BeginMainFrame( } // If the commit finishes, LayerTreeHost will transfer its swap promises to - // LayerTreeImpl. The destructor of ScopedSwapPromiseChecker aborts the - // remaining swap promises. - ScopedAbortRemainingSwapPromises swap_promise_checker(layer_tree_host()); + // LayerTreeImpl. The destructor of SwapPromiseChecker checks LayerTressHost's + // swap promises. + SwapPromiseChecker swap_promise_checker(layer_tree_host()); main().commit_requested = false; main().commit_request_sent_to_impl_thread = false; diff --git a/chrome/browser/ui/views/menu_view_drag_and_drop_test.cc b/chrome/browser/ui/views/menu_view_drag_and_drop_test.cc index 7fb4ec8..4e9c4ae 100644 --- a/chrome/browser/ui/views/menu_view_drag_and_drop_test.cc +++ b/chrome/browser/ui/views/menu_view_drag_and_drop_test.cc @@ -17,9 +17,8 @@ namespace { // Borrowed from chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc, // since these are also disabled on Linux for drag and drop. -// TODO(erg): Fix DND tests on linux_aura. http://crbug.com/163931 -// TODO(enne): Windows version has flaky timeouts. http://crbug.com/401226 -#if defined(USE_AURA) +// TODO(erg): Fix DND tests on linux_aura. crbug.com/163931 +#if defined(OS_LINUX) && defined(USE_AURA) #define MAYBE(x) DISABLED_##x #else #define MAYBE(x) x diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc index 13b0735..3ca74a2 100644 --- a/content/browser/renderer_host/compositor_impl_android.cc +++ b/content/browser/renderer_host/compositor_impl_android.cc @@ -314,6 +314,7 @@ void CompositorImpl::Composite(CompositingTrigger trigger) { // animation updates that will already be reflected in the current frame // we are about to draw. ignore_schedule_composite_ = true; + client_->Layout(); const base::TimeTicks frame_time = gfx::FrameTime::Now(); if (needs_animate_) { @@ -425,6 +426,7 @@ void CompositorImpl::SetVisible(bool visible) { } else if (!host_) { DCHECK(!WillComposite()); needs_composite_ = false; + needs_animate_ = false; pending_swapbuffers_ = 0; cc::LayerTreeSettings settings; settings.refresh_rate = 60.0; @@ -439,8 +441,6 @@ void CompositorImpl::SetVisible(bool visible) { command_line->HasSwitch(cc::switches::kEnableGpuBenchmarking)); settings.initial_debug_state.show_fps_counter = command_line->HasSwitch(cc::switches::kUIShowFPSCounter); - // TODO(enne): Update this this compositor to use the scheduler. - settings.single_thread_proxy_scheduler = false; host_ = cc::LayerTreeHost::CreateSingleThreaded( this, @@ -523,9 +523,10 @@ CreateGpuProcessViewContext( } void CompositorImpl::Layout() { - ignore_schedule_composite_ = true; + // TODO: If we get this callback from the SingleThreadProxy, we need + // to stop calling it ourselves in CompositorImpl::Composite(). + NOTREACHED(); client_->Layout(); - ignore_schedule_composite_ = false; } scoped_ptr<cc::OutputSurface> CompositorImpl::CreateOutputSurface( @@ -574,6 +575,7 @@ void CompositorImpl::ScheduleComposite() { } void CompositorImpl::ScheduleAnimation() { + DCHECK(!needs_animate_ || needs_composite_); DCHECK(!needs_composite_ || WillComposite()); needs_animate_ = true; @@ -603,7 +605,6 @@ void CompositorImpl::DidAbortSwapBuffers() { // This really gets called only once from // SingleThreadProxy::DidLoseOutputSurfaceOnImplThread() when the // context was lost. - ScheduleComposite(); client_->OnSwapBuffersCompleted(0); } diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc index 0fc9e87..43bbe32 100644 --- a/content/public/common/content_switches.cc +++ b/content/public/common/content_switches.cc @@ -246,10 +246,6 @@ const char kDisableSetuidSandbox[] = "disable-setuid-sandbox"; // Disable shared workers. const char kDisableSharedWorkers[] = "disable-shared-workers"; -// For tests, disable single thread scheduler and only manually composite. -const char kDisableSingleThreadProxyScheduler[] = - "disable-single-thread-proxy-scheduler"; - // Disable smooth scrolling for testing. const char kDisableSmoothScrolling[] = "disable-smooth-scrolling"; diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h index 0477a6a..69add0a 100644 --- a/content/public/common/content_switches.h +++ b/content/public/common/content_switches.h @@ -79,7 +79,6 @@ CONTENT_EXPORT extern const char kDisableSeccompFilterSandbox[]; extern const char kDisableSessionStorage[]; CONTENT_EXPORT extern const char kDisableSetuidSandbox[]; CONTENT_EXPORT extern const char kDisableSharedWorkers[]; -CONTENT_EXPORT extern const char kDisableSingleThreadProxyScheduler[]; CONTENT_EXPORT extern const char kDisableSmoothScrolling[]; CONTENT_EXPORT extern const char kDisableSoftwareRasterizer[]; CONTENT_EXPORT extern const char kDisableThreadedCompositing[]; diff --git a/content/renderer/gpu/render_widget_compositor.cc b/content/renderer/gpu/render_widget_compositor.cc index baf1ac1..23230ee 100644 --- a/content/renderer/gpu/render_widget_compositor.cc +++ b/content/renderer/gpu/render_widget_compositor.cc @@ -277,8 +277,6 @@ scoped_ptr<RenderWidgetCompositor> RenderWidgetCompositor::Create( cmd->HasSwitch(cc::switches::kEnablePinchVirtualViewport); settings.allow_antialiasing &= !cmd->HasSwitch(cc::switches::kDisableCompositedAntialiasing); - settings.single_thread_proxy_scheduler = - !cmd->HasSwitch(switches::kDisableSingleThreadProxyScheduler); // These flags should be mirrored by UI versions in ui/compositor/. settings.initial_debug_state.show_debug_borders = @@ -411,6 +409,7 @@ scoped_ptr<RenderWidgetCompositor> RenderWidgetCompositor::Create( RenderWidgetCompositor::RenderWidgetCompositor(RenderWidget* widget, bool threaded) : threaded_(threaded), + suppress_schedule_composite_(false), widget_(widget) { } @@ -421,10 +420,27 @@ RenderWidgetCompositor::GetInputHandler() { return layer_tree_host_->GetInputHandler(); } +void RenderWidgetCompositor::SetSuppressScheduleComposite(bool suppress) { + if (suppress_schedule_composite_ == suppress) + return; + + if (suppress) + TRACE_EVENT_ASYNC_BEGIN0( + "gpu", "RenderWidgetCompositor::SetSuppressScheduleComposite", this); + else + TRACE_EVENT_ASYNC_END0( + "gpu", "RenderWidgetCompositor::SetSuppressScheduleComposite", this); + suppress_schedule_composite_ = suppress; +} + bool RenderWidgetCompositor::BeginMainFrameRequested() const { return layer_tree_host_->BeginMainFrameRequested(); } +void RenderWidgetCompositor::UpdateAnimations(base::TimeTicks time) { + layer_tree_host_->UpdateClientAnimations(time); +} + void RenderWidgetCompositor::SetNeedsDisplayOnAllLayers() { layer_tree_host_->SetNeedsDisplayOnAllLayers(); } @@ -533,10 +549,7 @@ void RenderWidgetCompositor::Initialize(cc::LayerTreeSettings settings) { } void RenderWidgetCompositor::setSurfaceReady() { - // In tests without a RenderThreadImpl, don't set ready as this kicks - // off creating output surfaces that the test can't create. - if (RenderThreadImpl::current()) - layer_tree_host_->SetLayerTreeHostClientReady(); + layer_tree_host_->SetLayerTreeHostClientReady(); } void RenderWidgetCompositor::setRootLayer(const blink::WebLayer& layer) { @@ -689,9 +702,9 @@ void RenderWidgetCompositor::compositeAndReadbackAsync( cc::CopyOutputRequest::CreateBitmapRequest( base::Bind(&CompositeAndReadbackAsyncCallback, callback)); layer_tree_host_->root_layer()->RequestCopyOfOutput(request.Pass()); - - if (!threaded_ && - !layer_tree_host_->settings().single_thread_proxy_scheduler) { + if (!threaded_) { + widget_->webwidget()->animate(0.0); + widget_->webwidget()->layout(); layer_tree_host_->Composite(gfx::FrameTime::Now()); } } @@ -787,6 +800,11 @@ void RenderWidgetCompositor::DidCompleteSwapBuffers() { widget_->OnSwapBuffersComplete(); } +void RenderWidgetCompositor::ScheduleComposite() { + if (!suppress_schedule_composite_) + widget_->scheduleComposite(); +} + void RenderWidgetCompositor::ScheduleAnimation() { widget_->scheduleAnimation(); } diff --git a/content/renderer/gpu/render_widget_compositor.h b/content/renderer/gpu/render_widget_compositor.h index 79a03b4..e0541ec 100644 --- a/content/renderer/gpu/render_widget_compositor.h +++ b/content/renderer/gpu/render_widget_compositor.h @@ -44,7 +44,9 @@ class RenderWidgetCompositor : public blink::WebLayerTreeView, virtual ~RenderWidgetCompositor(); const base::WeakPtr<cc::InputHandler>& GetInputHandler(); + void SetSuppressScheduleComposite(bool suppress); bool BeginMainFrameRequested() const; + void UpdateAnimations(base::TimeTicks time); void SetNeedsDisplayOnAllLayers(); void SetRasterizeOnlyVisibleContent(); void UpdateTopControlsState(cc::TopControlsState constraints, @@ -141,6 +143,7 @@ class RenderWidgetCompositor : public blink::WebLayerTreeView, virtual void RateLimitSharedMainThreadContext() OVERRIDE; // cc::LayerTreeHostSingleThreadClient implementation. + virtual void ScheduleComposite() OVERRIDE; virtual void ScheduleAnimation() OVERRIDE; virtual void DidPostSwapBuffers() OVERRIDE; virtual void DidAbortSwapBuffers() OVERRIDE; @@ -151,6 +154,7 @@ class RenderWidgetCompositor : public blink::WebLayerTreeView, void Initialize(cc::LayerTreeSettings settings); bool threaded_; + bool suppress_schedule_composite_; RenderWidget* widget_; scoped_ptr<cc::LayerTreeHost> layer_tree_host_; }; diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc index 7e7fb2d..10d87e1 100644 --- a/content/renderer/render_widget.cc +++ b/content/renderer/render_widget.cc @@ -393,7 +393,6 @@ RenderWidget::RenderWidget(blink::WebPopupType popup_type, handling_event_type_(WebInputEvent::Undefined), ignore_ack_for_mouse_move_from_debugger_(false), closing_(false), - host_closing_(false), is_swapped_out_(swapped_out), input_method_is_active_(false), text_input_type_(ui::TEXT_INPUT_TYPE_NONE), @@ -1202,8 +1201,6 @@ void RenderWidget::AutoResizeCompositor() { } void RenderWidget::initializeLayerTreeView() { - DCHECK(!host_closing_); - compositor_ = RenderWidgetCompositor::Create(this, IsThreadedCompositingEnabled()); compositor_->setViewportSize(size_, physical_backing_size_); @@ -1211,20 +1208,20 @@ void RenderWidget::initializeLayerTreeView() { StartCompositor(); } -void RenderWidget::DestroyLayerTreeView() { - // Always send this notification to prevent new layer tree views from - // being created, even if one hasn't been created yet. - webwidget_->willCloseLayerTreeView(); - compositor_.reset(); -} - blink::WebLayerTreeView* RenderWidget::layerTreeView() { return compositor_.get(); } +void RenderWidget::suppressCompositorScheduling(bool enable) { + if (compositor_) + compositor_->SetSuppressScheduleComposite(enable); +} + void RenderWidget::willBeginCompositorFrame() { TRACE_EVENT0("gpu", "RenderWidget::willBeginCompositorFrame"); + DCHECK(RenderThreadImpl::current()->compositor_message_loop_proxy().get()); + // The following two can result in further layout and possibly // enable GPU acceleration so they need to be called before any painting // is done. @@ -1381,12 +1378,6 @@ void RenderWidget::didBlur() { } void RenderWidget::DoDeferredClose() { - // No more compositing is possible. This prevents shutdown races between - // previously posted CreateOutputSurface tasks and the host being unable to - // create them because the close message was handled. - DestroyLayerTreeView(); - // Also prevent new compositors from being created. - host_closing_ = true; Send(new ViewHostMsg_Close(routing_id_)); } @@ -1427,7 +1418,8 @@ void RenderWidget::QueueSyntheticGesture( void RenderWidget::Close() { screen_metrics_emulator_.reset(); if (webwidget_) { - DestroyLayerTreeView(); + webwidget_->willCloseLayerTreeView(); + compositor_.reset(); webwidget_->close(); webwidget_ = NULL; } diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h index 22612a5..bd97588 100644 --- a/content/renderer/render_widget.h +++ b/content/renderer/render_widget.h @@ -142,6 +142,7 @@ class CONTENT_EXPORT RenderWidget virtual bool Send(IPC::Message* msg) OVERRIDE; // blink::WebWidgetClient + virtual void suppressCompositorScheduling(bool enable); virtual void willBeginCompositorFrame(); virtual void didAutoResize(const blink::WebSize& new_size); virtual void initializeLayerTreeView(); @@ -172,9 +173,6 @@ class CONTENT_EXPORT RenderWidget // Begins the compositor's scheduler to start producing frames. void StartCompositor(); - // Stop compositing. - void DestroyLayerTreeView(); - // Called when a plugin is moved. These events are queued up and sent with // the next paint or scroll message to the host. void SchedulePluginMove(const WebPluginGeometry& move); @@ -626,9 +624,6 @@ class CONTENT_EXPORT RenderWidget // be sent, except for a Close. bool closing_; - // True if it is known that the host is in the process of being shut down. - bool host_closing_; - // Whether this RenderWidget is currently swapped out, such that the view is // being rendered by another process. If all RenderWidgets in a process are // swapped out, the process can exit. diff --git a/content/shell/renderer/test_runner/web_test_proxy.cc b/content/shell/renderer/test_runner/web_test_proxy.cc index 18086de..7e36976 100644 --- a/content/shell/renderer/test_runner/web_test_proxy.cc +++ b/content/shell/renderer/test_runner/web_test_proxy.cc @@ -7,11 +7,9 @@ #include <cctype> #include "base/callback_helpers.h" -#include "base/command_line.h" #include "base/debug/trace_event.h" #include "base/logging.h" #include "base/strings/stringprintf.h" -#include "content/public/common/content_switches.h" #include "content/shell/renderer/test_runner/TestPlugin.h" #include "content/shell/renderer/test_runner/WebTestDelegate.h" #include "content/shell/renderer/test_runner/WebTestInterfaces.h" @@ -315,10 +313,6 @@ WebTestProxyBase::WebTestProxyBase() web_widget_(NULL), spellcheck_(new SpellCheckClient(this)), chooser_count_(0) { - // TODO(enne): using the scheduler introduces additional composite steps - // that create flakiness. This should go away eventually. - base::CommandLine::ForCurrentProcess()->AppendSwitch( - switches::kDisableSingleThreadProxyScheduler); Reset(); } diff --git a/content/test/web_layer_tree_view_impl_for_testing.h b/content/test/web_layer_tree_view_impl_for_testing.h index 730c210..13d6ee4 100644 --- a/content/test/web_layer_tree_view_impl_for_testing.h +++ b/content/test/web_layer_tree_view_impl_for_testing.h @@ -80,6 +80,8 @@ class WebLayerTreeViewImplForTesting virtual void DidCompleteSwapBuffers() OVERRIDE {} // cc::LayerTreeHostSingleThreadClient implementation. + virtual void ScheduleComposite() OVERRIDE {} + virtual void ScheduleAnimation() OVERRIDE {} virtual void DidPostSwapBuffers() OVERRIDE {} virtual void DidAbortSwapBuffers() OVERRIDE {} diff --git a/ui/compositor/compositor.cc b/ui/compositor/compositor.cc index 6be8530..fce83d6 100644 --- a/ui/compositor/compositor.cc +++ b/ui/compositor/compositor.cc @@ -61,6 +61,12 @@ void CompositorLock::CancelLock() { compositor_ = NULL; } +} // namespace ui + +namespace {} // namespace + +namespace ui { + Compositor::Compositor(gfx::AcceleratedWidget widget, ui::ContextFactory* context_factory, scoped_refptr<base::SingleThreadTaskRunner> task_runner) @@ -71,9 +77,16 @@ Compositor::Compositor(gfx::AcceleratedWidget widget, task_runner_(task_runner), vsync_manager_(new CompositorVSyncManager()), device_scale_factor_(0.0f), + last_started_frame_(0), + last_ended_frame_(0), disable_schedule_composite_(false), compositor_lock_(NULL), - layer_animator_collection_(this) { + defer_draw_scheduling_(false), + waiting_on_compositing_end_(false), + draw_on_compositing_end_(false), + swap_state_(SWAP_NONE), + layer_animator_collection_(this), + schedule_draw_factory_(this) { root_web_layer_ = cc::Layer::Create(); CommandLine* command_line = CommandLine::ForCurrentProcess(); @@ -162,7 +175,14 @@ Compositor::~Compositor() { } void Compositor::ScheduleDraw() { - host_->SetNeedsCommit(); + if (compositor_thread_loop_) { + host_->SetNeedsCommit(); + } else if (!defer_draw_scheduling_) { + defer_draw_scheduling_ = true; + task_runner_->PostTask( + FROM_HERE, + base::Bind(&Compositor::Draw, schedule_draw_factory_.GetWeakPtr())); + } } void Compositor::SetRootLayer(Layer* root_layer) { @@ -183,19 +203,42 @@ void Compositor::SetHostHasTransparentBackground( host_->set_has_transparent_background(host_has_transparent_background); } +void Compositor::Draw() { + DCHECK(!compositor_thread_loop_); + + defer_draw_scheduling_ = false; + if (waiting_on_compositing_end_) { + draw_on_compositing_end_ = true; + return; + } + if (!root_layer_) + return; + + TRACE_EVENT_ASYNC_BEGIN0("ui", "Compositor::Draw", last_started_frame_ + 1); + + DCHECK_NE(swap_state_, SWAP_POSTED); + swap_state_ = SWAP_NONE; + + waiting_on_compositing_end_ = true; + last_started_frame_++; + if (!IsLocked()) { + // TODO(nduca): Temporary while compositor calls + // compositeImmediately() directly. + base::TimeTicks now = gfx::FrameTime::Now(); + Animate(now); + Layout(); + host_->Composite(now); + } + if (swap_state_ == SWAP_NONE) + NotifyEnd(); +} + void Compositor::ScheduleFullRedraw() { - // TODO(enne): Some callers (mac) call this function expecting that it - // will also commit. This should probably just redraw the screen - // from damage and not commit. ScheduleDraw/ScheduleRedraw need - // better names. host_->SetNeedsRedraw(); - host_->SetNeedsCommit(); } void Compositor::ScheduleRedrawRect(const gfx::Rect& damage_rect) { - // TODO(enne): Make this not commit. See ScheduleFullRedraw. host_->SetNeedsRedrawRect(damage_rect); - host_->SetNeedsCommit(); } void Compositor::FinishAllRendering() { @@ -302,30 +345,45 @@ void Compositor::DidCommit() { } void Compositor::DidCommitAndDrawFrame() { + base::TimeTicks start_time = gfx::FrameTime::Now(); + FOR_EACH_OBSERVER(CompositorObserver, + observer_list_, + OnCompositingStarted(this, start_time)); } void Compositor::DidCompleteSwapBuffers() { - // DidPostSwapBuffers is a SingleThreadProxy-only feature. Synthetically - // generate OnCompositingStarted messages for the threaded case so that - // OnCompositingStarted/OnCompositingEnded messages match. if (compositor_thread_loop_) { - base::TimeTicks start_time = gfx::FrameTime::Now(); - FOR_EACH_OBSERVER(CompositorObserver, - observer_list_, - OnCompositingStarted(this, start_time)); + NotifyEnd(); + } else { + DCHECK_EQ(swap_state_, SWAP_POSTED); + NotifyEnd(); + swap_state_ = SWAP_COMPLETED; } - FOR_EACH_OBSERVER( - CompositorObserver, observer_list_, OnCompositingEnded(this)); +} + +void Compositor::ScheduleComposite() { + if (!disable_schedule_composite_) + ScheduleDraw(); +} + +void Compositor::ScheduleAnimation() { + ScheduleComposite(); } void Compositor::DidPostSwapBuffers() { - base::TimeTicks start_time = gfx::FrameTime::Now(); - FOR_EACH_OBSERVER(CompositorObserver, - observer_list_, - OnCompositingStarted(this, start_time)); + DCHECK(!compositor_thread_loop_); + DCHECK_EQ(swap_state_, SWAP_NONE); + swap_state_ = SWAP_POSTED; } void Compositor::DidAbortSwapBuffers() { + if (!compositor_thread_loop_) { + if (swap_state_ == SWAP_POSTED) { + NotifyEnd(); + swap_state_ = SWAP_COMPLETED; + } + } + FOR_EACH_OBSERVER(CompositorObserver, observer_list_, OnCompositingAborted(this)); @@ -343,7 +401,8 @@ void Compositor::SetLayerTreeDebugState( scoped_refptr<CompositorLock> Compositor::GetCompositorLock() { if (!compositor_lock_) { compositor_lock_ = new CompositorLock(this); - host_->SetDeferCommits(true); + if (compositor_thread_loop_) + host_->SetDeferCommits(true); FOR_EACH_OBSERVER(CompositorObserver, observer_list_, OnCompositingLockStateChanged(this)); @@ -354,7 +413,8 @@ scoped_refptr<CompositorLock> Compositor::GetCompositorLock() { void Compositor::UnlockCompositor() { DCHECK(compositor_lock_); compositor_lock_ = NULL; - host_->SetDeferCommits(false); + if (compositor_thread_loop_) + host_->SetDeferCommits(false); FOR_EACH_OBSERVER(CompositorObserver, observer_list_, OnCompositingLockStateChanged(this)); @@ -365,4 +425,20 @@ void Compositor::CancelCompositorLock() { compositor_lock_->CancelLock(); } +void Compositor::NotifyEnd() { + last_ended_frame_++; + TRACE_EVENT_ASYNC_END0("ui", "Compositor::Draw", last_ended_frame_); + waiting_on_compositing_end_ = false; + if (draw_on_compositing_end_) { + draw_on_compositing_end_ = false; + + // Call ScheduleDraw() instead of Draw() in order to allow other + // CompositorObservers to be notified before starting another + // draw cycle. + ScheduleDraw(); + } + FOR_EACH_OBSERVER( + CompositorObserver, observer_list_, OnCompositingEnded(this)); +} + } // namespace ui diff --git a/ui/compositor/compositor.h b/ui/compositor/compositor.h index b2d2779..0e4ac8a 100644 --- a/ui/compositor/compositor.h +++ b/ui/compositor/compositor.h @@ -24,6 +24,8 @@ #include "ui/gfx/size.h" #include "ui/gfx/vector2d.h" +class SkBitmap; + namespace base { class MessageLoopProxy; class RunLoop; @@ -157,6 +159,9 @@ class COMPOSITOR_EXPORT Compositor // compositing layers on. float device_scale_factor() const { return device_scale_factor_; } + // Draws the scene created by the layer tree and any visual effects. + void Draw(); + // Where possible, draws are scissored to a damage region calculated from // changes to layer properties. This bypasses that and indicates that // the whole frame needs to be drawn. @@ -229,9 +234,14 @@ class COMPOSITOR_EXPORT Compositor virtual void DidCompleteSwapBuffers() OVERRIDE; // cc::LayerTreeHostSingleThreadClient implementation. + virtual void ScheduleComposite() OVERRIDE; + virtual void ScheduleAnimation() OVERRIDE; virtual void DidPostSwapBuffers() OVERRIDE; virtual void DidAbortSwapBuffers() OVERRIDE; + int last_started_frame() { return last_started_frame_; } + int last_ended_frame() { return last_ended_frame_; } + bool IsLocked() { return compositor_lock_ != NULL; } const cc::LayerTreeDebugState& GetLayerTreeDebugState() const; @@ -251,6 +261,9 @@ class COMPOSITOR_EXPORT Compositor // Called to release any pending CompositorLock void CancelCompositorLock(); + // Notifies the compositor that compositing is complete. + void NotifyEnd(); + gfx::Size size_; ui::ContextFactory* context_factory_; @@ -281,8 +294,19 @@ class COMPOSITOR_EXPORT Compositor CompositorLock* compositor_lock_; + // Prevent more than one draw from being scheduled. + bool defer_draw_scheduling_; + + // Used to prevent Draw()s while a composite is in progress. + bool waiting_on_compositing_end_; + bool draw_on_compositing_end_; + enum SwapState { SWAP_NONE, SWAP_POSTED, SWAP_COMPLETED }; + SwapState swap_state_; + LayerAnimatorCollection layer_animator_collection_; + base::WeakPtrFactory<Compositor> schedule_draw_factory_; + DISALLOW_COPY_AND_ASSIGN(Compositor); }; diff --git a/ui/compositor/layer_unittest.cc b/ui/compositor/layer_unittest.cc index b5c473c..9cb80c4 100644 --- a/ui/compositor/layer_unittest.cc +++ b/ui/compositor/layer_unittest.cc @@ -126,7 +126,7 @@ class LayerWithRealCompositorTest : public testing::Test { void DrawTree(Layer* root) { GetCompositor()->SetRootLayer(root); GetCompositor()->ScheduleDraw(); - WaitForSwap(); + WaitForDraw(); } bool ReadPixels(SkBitmap* bitmap) { @@ -142,13 +142,11 @@ class LayerWithRealCompositorTest : public testing::Test { GetCompositor()->root_layer()->RequestCopyOfOutput(request.Pass()); - // Wait for copy response. The copy output request will get committed - // before the first draw, but may not be part of the first draw's frame. - // The second draw will perform the async copy request, post the callback. - // The second loop finishes before the callback is run, so a third - // loop is needed. - for (int i = 0; i < 3; i++) { - GetCompositor()->ScheduleFullRedraw(); + // Wait for copy response. This needs to wait as the compositor could + // be in the middle of a draw right now, and the commit with the + // copy output request may not be done on the first draw. + for (int i = 0; i < 2; i++) { + GetCompositor()->ScheduleDraw(); WaitForDraw(); } @@ -162,13 +160,7 @@ class LayerWithRealCompositorTest : public testing::Test { return false; } - void WaitForDraw() { - ui::DrawWaiterForTest::WaitForCompositingStarted(GetCompositor()); - } - - void WaitForSwap() { - DrawWaiterForTest::WaitForCompositingEnded(GetCompositor()); - } + void WaitForDraw() { ui::DrawWaiterForTest::Wait(GetCompositor()); } void WaitForCommit() { ui::DrawWaiterForTest::WaitForCommit(GetCompositor()); @@ -455,9 +447,7 @@ class LayerWithDelegateTest : public testing::Test { WaitForDraw(); } - void WaitForDraw() { - DrawWaiterForTest::WaitForCompositingStarted(compositor()); - } + void WaitForDraw() { DrawWaiterForTest::Wait(compositor()); } void WaitForCommit() { DrawWaiterForTest::WaitForCommit(compositor()); @@ -951,25 +941,25 @@ TEST_F(LayerWithRealCompositorTest, CompositorObservers) { // Moving, but not resizing, a layer should alert the observers. observer.Reset(); l2->SetBounds(gfx::Rect(0, 0, 350, 350)); - WaitForSwap(); + WaitForDraw(); EXPECT_TRUE(observer.notified()); // So should resizing a layer. observer.Reset(); l2->SetBounds(gfx::Rect(0, 0, 400, 400)); - WaitForSwap(); + WaitForDraw(); EXPECT_TRUE(observer.notified()); // Opacity changes should alert the observers. observer.Reset(); l2->SetOpacity(0.5f); - WaitForSwap(); + WaitForDraw(); EXPECT_TRUE(observer.notified()); // So should setting the opacity back. observer.Reset(); l2->SetOpacity(1.0f); - WaitForSwap(); + WaitForDraw(); EXPECT_TRUE(observer.notified()); // Setting the transform of a layer should alert the observers. @@ -979,7 +969,7 @@ TEST_F(LayerWithRealCompositorTest, CompositorObservers) { transform.Rotate(90.0); transform.Translate(-200.0, -200.0); l2->SetTransform(transform); - WaitForSwap(); + WaitForDraw(); EXPECT_TRUE(observer.notified()); // A change resulting in an aborted swap buffer should alert the observer @@ -987,7 +977,7 @@ TEST_F(LayerWithRealCompositorTest, CompositorObservers) { observer.Reset(); l2->SetOpacity(0.1f); GetCompositor()->DidAbortSwapBuffers(); - WaitForSwap(); + WaitForDraw(); EXPECT_TRUE(observer.notified()); EXPECT_TRUE(observer.aborted()); @@ -996,7 +986,7 @@ TEST_F(LayerWithRealCompositorTest, CompositorObservers) { // Opacity changes should no longer alert the removed observer. observer.Reset(); l2->SetOpacity(0.5f); - WaitForSwap(); + WaitForDraw(); EXPECT_FALSE(observer.notified()); } diff --git a/ui/compositor/test/draw_waiter_for_test.cc b/ui/compositor/test/draw_waiter_for_test.cc index f256ecc..7687d66 100644 --- a/ui/compositor/test/draw_waiter_for_test.cc +++ b/ui/compositor/test/draw_waiter_for_test.cc @@ -9,24 +9,20 @@ namespace ui { // static -void DrawWaiterForTest::WaitForCompositingStarted(Compositor* compositor) { - DrawWaiterForTest waiter(WAIT_FOR_COMPOSITING_STARTED); - waiter.WaitImpl(compositor); -} - -void DrawWaiterForTest::WaitForCompositingEnded(Compositor* compositor) { - DrawWaiterForTest waiter(WAIT_FOR_COMPOSITING_ENDED); +void DrawWaiterForTest::Wait(Compositor* compositor) { + DrawWaiterForTest waiter; + waiter.wait_for_commit_ = false; waiter.WaitImpl(compositor); } // static void DrawWaiterForTest::WaitForCommit(Compositor* compositor) { - DrawWaiterForTest waiter(WAIT_FOR_COMMIT); + DrawWaiterForTest waiter; + waiter.wait_for_commit_ = true; waiter.WaitImpl(compositor); } -DrawWaiterForTest::DrawWaiterForTest(WaitEvent wait_event) - : wait_event_(wait_event) { +DrawWaiterForTest::DrawWaiterForTest() { } DrawWaiterForTest::~DrawWaiterForTest() {} @@ -39,18 +35,16 @@ void DrawWaiterForTest::WaitImpl(Compositor* compositor) { } void DrawWaiterForTest::OnCompositingDidCommit(Compositor* compositor) { - if (wait_event_ == WAIT_FOR_COMMIT) + if (wait_for_commit_) wait_run_loop_->Quit(); } void DrawWaiterForTest::OnCompositingStarted(Compositor* compositor, base::TimeTicks start_time) { - if (wait_event_ == WAIT_FOR_COMPOSITING_STARTED) - wait_run_loop_->Quit(); } void DrawWaiterForTest::OnCompositingEnded(Compositor* compositor) { - if (wait_event_ == WAIT_FOR_COMPOSITING_ENDED) + if (!wait_for_commit_) wait_run_loop_->Quit(); } diff --git a/ui/compositor/test/draw_waiter_for_test.h b/ui/compositor/test/draw_waiter_for_test.h index e1d63ff..051c58f 100644 --- a/ui/compositor/test/draw_waiter_for_test.h +++ b/ui/compositor/test/draw_waiter_for_test.h @@ -20,22 +20,13 @@ class DrawWaiterForTest : public CompositorObserver { // Waits for a draw to be issued by the compositor. If the test times out // here, there may be a logic error in the compositor code causing it // not to draw. - static void WaitForCompositingStarted(Compositor* compositor); - - // Waits for a swap to be completed from the compositor. - static void WaitForCompositingEnded(Compositor* compositor); + static void Wait(Compositor* compositor); // Waits for a commit instead of a draw. static void WaitForCommit(Compositor* compositor); private: - enum WaitEvent { - WAIT_FOR_COMMIT, - WAIT_FOR_COMPOSITING_STARTED, - WAIT_FOR_COMPOSITING_ENDED, - }; - - DrawWaiterForTest(WaitEvent wait_event); + DrawWaiterForTest(); virtual ~DrawWaiterForTest(); void WaitImpl(Compositor* compositor); @@ -50,7 +41,7 @@ class DrawWaiterForTest : public CompositorObserver { scoped_ptr<base::RunLoop> wait_run_loop_; - WaitEvent wait_event_; + bool wait_for_commit_; DISALLOW_COPY_AND_ASSIGN(DrawWaiterForTest); }; diff --git a/ui/compositor/test/test_compositor_host_mac.mm b/ui/compositor/test/test_compositor_host_mac.mm index 7201fde..8d533d0 100644 --- a/ui/compositor/test/test_compositor_host_mac.mm +++ b/ui/compositor/test/test_compositor_host_mac.mm @@ -40,7 +40,7 @@ - (void)drawRect:(NSRect)rect { DCHECK(compositor_) << "Drawing with no compositor set."; - compositor_->ScheduleFullRedraw(); + compositor_->Draw(); } @end diff --git a/ui/compositor/test/test_compositor_host_ozone.cc b/ui/compositor/test/test_compositor_host_ozone.cc index 903c3b6..1c4b0cc 100644 --- a/ui/compositor/test/test_compositor_host_ozone.cc +++ b/ui/compositor/test/test_compositor_host_ozone.cc @@ -27,6 +27,8 @@ class TestCompositorHostOzone : public TestCompositorHost { virtual void Show() OVERRIDE; virtual ui::Compositor* GetCompositor() OVERRIDE; + void Draw(); + gfx::Rect bounds_; ui::ContextFactory* context_factory_; @@ -62,6 +64,11 @@ ui::Compositor* TestCompositorHostOzone::GetCompositor() { return compositor_.get(); } +void TestCompositorHostOzone::Draw() { + if (compositor_.get()) + compositor_->Draw(); +} + // static TestCompositorHost* TestCompositorHost::Create( const gfx::Rect& bounds, diff --git a/ui/compositor/test/test_compositor_host_win.cc b/ui/compositor/test/test_compositor_host_win.cc index 80db4ae..9c732f6 100644 --- a/ui/compositor/test/test_compositor_host_win.cc +++ b/ui/compositor/test/test_compositor_host_win.cc @@ -42,7 +42,7 @@ class TestCompositorHostWin : public TestCompositorHost, CR_END_MSG_MAP() void OnPaint(HDC dc) { - compositor_->ScheduleFullRedraw(); + compositor_->Draw(); ValidateRect(hwnd(), NULL); } diff --git a/ui/compositor/test/test_compositor_host_x11.cc b/ui/compositor/test/test_compositor_host_x11.cc index 1c3f674..9b2d265 100644 --- a/ui/compositor/test/test_compositor_host_x11.cc +++ b/ui/compositor/test/test_compositor_host_x11.cc @@ -30,6 +30,8 @@ class TestCompositorHostX11 : public TestCompositorHost { virtual void Show() OVERRIDE; virtual ui::Compositor* GetCompositor() OVERRIDE; + void Draw(); + gfx::Rect bounds_; ui::ContextFactory* context_factory_; @@ -83,6 +85,11 @@ ui::Compositor* TestCompositorHostX11::GetCompositor() { return compositor_.get(); } +void TestCompositorHostX11::Draw() { + if (compositor_.get()) + compositor_->Draw(); +} + // static TestCompositorHost* TestCompositorHost::Create( const gfx::Rect& bounds, diff --git a/ui/snapshot/snapshot_aura_unittest.cc b/ui/snapshot/snapshot_aura_unittest.cc index 018394b..5fe05a8 100644 --- a/ui/snapshot/snapshot_aura_unittest.cc +++ b/ui/snapshot/snapshot_aura_unittest.cc @@ -115,8 +115,7 @@ class SnapshotAuraTest : public testing::Test { void WaitForDraw() { helper_->host()->compositor()->ScheduleDraw(); - ui::DrawWaiterForTest::WaitForCompositingEnded( - helper_->host()->compositor()); + ui::DrawWaiterForTest::Wait(helper_->host()->compositor()); } void SetupTestWindow(const gfx::Rect& window_bounds) { diff --git a/ui/views/view_unittest.cc b/ui/views/view_unittest.cc index 87164b0..c4e6dcb 100644 --- a/ui/views/view_unittest.cc +++ b/ui/views/view_unittest.cc @@ -3087,23 +3087,20 @@ TEST_F(ViewLayerTest, DontPaintChildrenWithLayers) { widget()->SetContentsView(content_view); content_view->SetPaintToLayer(true); GetRootLayer()->GetCompositor()->ScheduleDraw(); - ui::DrawWaiterForTest::WaitForCompositingEnded( - GetRootLayer()->GetCompositor()); + ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor()); GetRootLayer()->SchedulePaint(gfx::Rect(0, 0, 10, 10)); content_view->set_painted(false); // content_view no longer has a dirty rect. Paint from the root and make sure // PaintTrackingView isn't painted. GetRootLayer()->GetCompositor()->ScheduleDraw(); - ui::DrawWaiterForTest::WaitForCompositingEnded( - GetRootLayer()->GetCompositor()); + ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor()); EXPECT_FALSE(content_view->painted()); // Make content_view have a dirty rect, paint the layers and make sure // PaintTrackingView is painted. content_view->layer()->SchedulePaint(gfx::Rect(0, 0, 10, 10)); GetRootLayer()->GetCompositor()->ScheduleDraw(); - ui::DrawWaiterForTest::WaitForCompositingEnded( - GetRootLayer()->GetCompositor()); + ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor()); EXPECT_TRUE(content_view->painted()); } @@ -3343,15 +3340,13 @@ TEST_F(ViewLayerTest, BoundsTreePaintUpdatesCullSet) { // Schedule a full-view paint to get everyone's rectangles updated. test_view->SchedulePaintInRect(test_view->bounds()); GetRootLayer()->GetCompositor()->ScheduleDraw(); - ui::DrawWaiterForTest::WaitForCompositingEnded( - GetRootLayer()->GetCompositor()); + ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor()); // Now we have test_view - v1 - v2. Damage to only test_view should only // return root_view and test_view. test_view->SchedulePaintInRect(gfx::Rect(0, 0, 1, 1)); GetRootLayer()->GetCompositor()->ScheduleDraw(); - ui::DrawWaiterForTest::WaitForCompositingEnded( - GetRootLayer()->GetCompositor()); + ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor()); EXPECT_EQ(2U, test_view->last_cull_set_.size()); EXPECT_EQ(1U, test_view->last_cull_set_.count(widget()->GetRootView())); EXPECT_EQ(1U, test_view->last_cull_set_.count(test_view)); @@ -3359,8 +3354,7 @@ TEST_F(ViewLayerTest, BoundsTreePaintUpdatesCullSet) { // Damage to v1 only should only return root_view, test_view, and v1. test_view->SchedulePaintInRect(gfx::Rect(11, 16, 1, 1)); GetRootLayer()->GetCompositor()->ScheduleDraw(); - ui::DrawWaiterForTest::WaitForCompositingEnded( - GetRootLayer()->GetCompositor()); + ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor()); EXPECT_EQ(3U, test_view->last_cull_set_.size()); EXPECT_EQ(1U, test_view->last_cull_set_.count(widget()->GetRootView())); EXPECT_EQ(1U, test_view->last_cull_set_.count(test_view)); @@ -3370,8 +3364,7 @@ TEST_F(ViewLayerTest, BoundsTreePaintUpdatesCullSet) { // on call to TestView::Paint(), along with the widget root view. test_view->SchedulePaintInRect(gfx::Rect(31, 49, 1, 1)); GetRootLayer()->GetCompositor()->ScheduleDraw(); - ui::DrawWaiterForTest::WaitForCompositingEnded( - GetRootLayer()->GetCompositor()); + ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor()); EXPECT_EQ(4U, test_view->last_cull_set_.size()); EXPECT_EQ(1U, test_view->last_cull_set_.count(widget()->GetRootView())); EXPECT_EQ(1U, test_view->last_cull_set_.count(test_view)); @@ -3398,15 +3391,13 @@ TEST_F(ViewLayerTest, BoundsTreeWithRTL) { // Schedule a full-view paint to get everyone's rectangles updated. test_view->SchedulePaintInRect(test_view->bounds()); GetRootLayer()->GetCompositor()->ScheduleDraw(); - ui::DrawWaiterForTest::WaitForCompositingEnded( - GetRootLayer()->GetCompositor()); + ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor()); // Damage to the right side of the parent view should touch both child views. gfx::Rect rtl_damage(test_view->bounds().width() - 16, 18, 1, 1); test_view->SchedulePaintInRect(rtl_damage); GetRootLayer()->GetCompositor()->ScheduleDraw(); - ui::DrawWaiterForTest::WaitForCompositingEnded( - GetRootLayer()->GetCompositor()); + ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor()); EXPECT_EQ(4U, test_view->last_cull_set_.size()); EXPECT_EQ(1U, test_view->last_cull_set_.count(widget()->GetRootView())); EXPECT_EQ(1U, test_view->last_cull_set_.count(test_view)); @@ -3418,8 +3409,7 @@ TEST_F(ViewLayerTest, BoundsTreeWithRTL) { gfx::Rect ltr_damage(16, 18, 1, 1); test_view->SchedulePaintInRect(ltr_damage); GetRootLayer()->GetCompositor()->ScheduleDraw(); - ui::DrawWaiterForTest::WaitForCompositingEnded( - GetRootLayer()->GetCompositor()); + ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor()); EXPECT_EQ(2U, test_view->last_cull_set_.size()); EXPECT_EQ(1U, test_view->last_cull_set_.count(widget()->GetRootView())); EXPECT_EQ(1U, test_view->last_cull_set_.count(test_view)); @@ -3443,21 +3433,18 @@ TEST_F(ViewLayerTest, BoundsTreeSetBoundsChangesCullSet) { // Schedule a full-view paint to get everyone's rectangles updated. test_view->SchedulePaintInRect(test_view->bounds()); GetRootLayer()->GetCompositor()->ScheduleDraw(); - ui::DrawWaiterForTest::WaitForCompositingEnded( - GetRootLayer()->GetCompositor()); + ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor()); // Move v1 to a new origin out of the way of our next query. v1->SetBoundsRect(gfx::Rect(50, 60, 100, 101)); // The move will force a repaint. GetRootLayer()->GetCompositor()->ScheduleDraw(); - ui::DrawWaiterForTest::WaitForCompositingEnded( - GetRootLayer()->GetCompositor()); + ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor()); // Schedule a paint with damage rect where v1 used to be. test_view->SchedulePaintInRect(gfx::Rect(5, 6, 10, 11)); GetRootLayer()->GetCompositor()->ScheduleDraw(); - ui::DrawWaiterForTest::WaitForCompositingEnded( - GetRootLayer()->GetCompositor()); + ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor()); // Should only have picked up root_view and test_view. EXPECT_EQ(2U, test_view->last_cull_set_.size()); @@ -3480,8 +3467,7 @@ TEST_F(ViewLayerTest, BoundsTreeLayerChangeMakesNewTree) { // Schedule a full-view paint to get everyone's rectangles updated. test_view->SchedulePaintInRect(test_view->bounds()); GetRootLayer()->GetCompositor()->ScheduleDraw(); - ui::DrawWaiterForTest::WaitForCompositingEnded( - GetRootLayer()->GetCompositor()); + ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor()); // Set v1 to paint to its own layer, it should remove itself from the // test_view heiarchy and no longer intersect with damage rects in that cull @@ -3491,8 +3477,7 @@ TEST_F(ViewLayerTest, BoundsTreeLayerChangeMakesNewTree) { // Schedule another full-view paint. test_view->SchedulePaintInRect(test_view->bounds()); GetRootLayer()->GetCompositor()->ScheduleDraw(); - ui::DrawWaiterForTest::WaitForCompositingEnded( - GetRootLayer()->GetCompositor()); + ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor()); // v1 and v2 should no longer be present in the test_view cull_set. EXPECT_EQ(2U, test_view->last_cull_set_.size()); EXPECT_EQ(0U, test_view->last_cull_set_.count(v1)); @@ -3503,8 +3488,7 @@ TEST_F(ViewLayerTest, BoundsTreeLayerChangeMakesNewTree) { // Schedule another full-view paint. test_view->SchedulePaintInRect(test_view->bounds()); GetRootLayer()->GetCompositor()->ScheduleDraw(); - ui::DrawWaiterForTest::WaitForCompositingEnded( - GetRootLayer()->GetCompositor()); + ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor()); // We should be back to the full cull set including v1 and v2. EXPECT_EQ(4U, test_view->last_cull_set_.size()); EXPECT_EQ(1U, test_view->last_cull_set_.count(widget()->GetRootView())); @@ -3528,8 +3512,7 @@ TEST_F(ViewLayerTest, BoundsTreeRemoveChildRemovesBounds) { // Schedule a full-view paint to get everyone's rectangles updated. test_view->SchedulePaintInRect(test_view->bounds()); GetRootLayer()->GetCompositor()->ScheduleDraw(); - ui::DrawWaiterForTest::WaitForCompositingEnded( - GetRootLayer()->GetCompositor()); + ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor()); // Now remove v1 from the root view. test_view->RemoveChildView(v1); @@ -3537,8 +3520,7 @@ TEST_F(ViewLayerTest, BoundsTreeRemoveChildRemovesBounds) { // Schedule another full-view paint. test_view->SchedulePaintInRect(test_view->bounds()); GetRootLayer()->GetCompositor()->ScheduleDraw(); - ui::DrawWaiterForTest::WaitForCompositingEnded( - GetRootLayer()->GetCompositor()); + ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor()); // v1 and v2 should no longer be present in the test_view cull_set. EXPECT_EQ(2U, test_view->last_cull_set_.size()); EXPECT_EQ(0U, test_view->last_cull_set_.count(v1)); @@ -3569,8 +3551,7 @@ TEST_F(ViewLayerTest, BoundsTreeMoveViewMovesBounds) { // Schedule a full-view paint and ensure all views are present in the cull. test_view->SchedulePaintInRect(test_view->bounds()); GetRootLayer()->GetCompositor()->ScheduleDraw(); - ui::DrawWaiterForTest::WaitForCompositingEnded( - GetRootLayer()->GetCompositor()); + ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor()); EXPECT_EQ(5U, test_view->last_cull_set_.size()); EXPECT_EQ(1U, test_view->last_cull_set_.count(widget()->GetRootView())); EXPECT_EQ(1U, test_view->last_cull_set_.count(test_view)); @@ -3593,8 +3574,7 @@ TEST_F(ViewLayerTest, BoundsTreeMoveViewMovesBounds) { test_view->SchedulePaintInRect(test_view->bounds()); widget_view->SchedulePaintInRect(widget_view->bounds()); GetRootLayer()->GetCompositor()->ScheduleDraw(); - ui::DrawWaiterForTest::WaitForCompositingEnded( - GetRootLayer()->GetCompositor()); + ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor()); // Only v1 should be present in the first cull set. EXPECT_EQ(3U, test_view->last_cull_set_.size()); |