summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--android_webview/browser/hardware_renderer.cc7
-rw-r--r--android_webview/browser/hardware_renderer.h2
-rw-r--r--cc/BUILD.gn1
-rw-r--r--cc/cc.gyp1
-rw-r--r--cc/scheduler/scheduler.cc27
-rw-r--r--cc/scheduler/scheduler.h15
-rw-r--r--cc/scheduler/scheduler_state_machine.cc4
-rw-r--r--cc/test/fake_layer_tree_host_client.h2
-rw-r--r--cc/test/layer_tree_test.cc48
-rw-r--r--cc/test/layer_tree_test.h6
-rw-r--r--cc/trees/layer_tree_host.cc4
-rw-r--r--cc/trees/layer_tree_host_perftest.cc2
-rw-r--r--cc/trees/layer_tree_host_single_thread_client.h4
-rw-r--r--cc/trees/layer_tree_host_unittest.cc91
-rw-r--r--cc/trees/layer_tree_host_unittest_animation.cc9
-rw-r--r--cc/trees/layer_tree_host_unittest_context.cc80
-rw-r--r--cc/trees/layer_tree_host_unittest_no_message_loop.cc3
-rw-r--r--cc/trees/layer_tree_settings.cc1
-rw-r--r--cc/trees/layer_tree_settings.h1
-rw-r--r--cc/trees/scoped_abort_remaining_swap_promises.h30
-rw-r--r--cc/trees/single_thread_proxy.cc370
-rw-r--r--cc/trees/single_thread_proxy.h47
-rw-r--r--cc/trees/thread_proxy.cc25
-rw-r--r--chrome/browser/ui/views/menu_view_drag_and_drop_test.cc5
-rw-r--r--content/browser/renderer_host/compositor_impl_android.cc11
-rw-r--r--content/public/common/content_switches.cc4
-rw-r--r--content/public/common/content_switches.h1
-rw-r--r--content/renderer/gpu/render_widget_compositor.cc36
-rw-r--r--content/renderer/gpu/render_widget_compositor.h4
-rw-r--r--content/renderer/render_widget.cc26
-rw-r--r--content/renderer/render_widget.h7
-rw-r--r--content/shell/renderer/test_runner/web_test_proxy.cc6
-rw-r--r--content/test/web_layer_tree_view_impl_for_testing.h2
-rw-r--r--ui/compositor/compositor.cc127
-rw-r--r--ui/compositor/compositor.h24
-rw-r--r--ui/compositor/layer_unittest.cc40
-rw-r--r--ui/compositor/test/draw_waiter_for_test.cc29
-rw-r--r--ui/compositor/test/draw_waiter_for_test.h15
-rw-r--r--ui/compositor/test/test_compositor_host_mac.mm2
-rw-r--r--ui/compositor/test/test_compositor_host_ozone.cc7
-rw-r--r--ui/compositor/test/test_compositor_host_win.cc2
-rw-r--r--ui/compositor/test/test_compositor_host_x11.cc7
-rw-r--r--ui/snapshot/snapshot_aura_unittest.cc3
-rw-r--r--ui/views/view_unittest.cc60
44 files changed, 695 insertions, 503 deletions
diff --git a/android_webview/browser/hardware_renderer.cc b/android_webview/browser/hardware_renderer.cc
index 818d3c5..86dd667 100644
--- a/android_webview/browser/hardware_renderer.cc
+++ b/android_webview/browser/hardware_renderer.cc
@@ -93,8 +93,11 @@ HardwareRenderer::HardwareRenderer(SharedRendererState* state)
// Webview does not own the surface so should not clear it.
settings.should_clear_root_render_pass = false;
- layer_tree_host_ = cc::LayerTreeHost::CreateSingleThreaded(
- this, this, NULL, settings, NULL);
+ // 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_);
layer_tree_host_->SetLayerTreeHostClientReady();
layer_tree_host_->set_has_transparent_background(true);
diff --git a/android_webview/browser/hardware_renderer.h b/android_webview/browser/hardware_renderer.h
index f87890b..b07d36d 100644
--- a/android_webview/browser/hardware_renderer.h
+++ b/android_webview/browser/hardware_renderer.h
@@ -54,8 +54,6 @@ 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 0688868..6a6cd02 100644
--- a/cc/BUILD.gn
+++ b/cc/BUILD.gn
@@ -451,6 +451,7 @@ 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",
diff --git a/cc/cc.gyp b/cc/cc.gyp
index 83d408e..c70aee1 100644
--- a/cc/cc.gyp
+++ b/cc/cc.gyp
@@ -480,6 +480,7 @@
'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 1451237..a20bfd2b 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>& impl_task_runner)
+ const scoped_refptr<base::SingleThreadTaskRunner>& task_runner)
: settings_(scheduler_settings),
client_(client),
layer_tree_host_id_(layer_tree_host_id),
- impl_task_runner_(impl_task_runner),
+ task_runner_(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, impl_task_runner_.get()));
+ new SyntheticBeginFrameSource(this, task_runner_.get()));
}
void Scheduler::CommitVSyncParameters(base::TimeTicks timebase,
@@ -274,6 +274,9 @@ base::TimeTicks Scheduler::LastBeginImplFrameTime() {
}
void Scheduler::SetupNextBeginFrameIfNeeded() {
+ if (!task_runner_)
+ return;
+
bool needs_begin_frame = state_machine_.BeginFrameNeeded();
if (settings_.throttle_frame_production) {
@@ -328,7 +331,7 @@ void Scheduler::SetupNextBeginFrameWhenVSyncThrottlingDisabled(
}
begin_unthrottled_frame_posted_ = true;
- impl_task_runner_->PostTask(FROM_HERE, begin_unthrottled_frame_closure_);
+ task_runner_->PostTask(FROM_HERE, begin_unthrottled_frame_closure_);
}
// BeginUnthrottledFrame is used when we aren't throttling frame production.
@@ -362,7 +365,7 @@ void Scheduler::SetupPollingMechanisms(bool needs_begin_frame) {
base::TimeDelta delay = begin_impl_frame_args_.IsValid()
? begin_impl_frame_args_.interval
: BeginFrameArgs::DefaultInterval();
- impl_task_runner_->PostDelayedTask(
+ task_runner_->PostDelayedTask(
FROM_HERE, poll_for_draw_triggers_task_.callback(), delay);
}
} else {
@@ -387,9 +390,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_);
- impl_task_runner_->PostDelayedTask(FROM_HERE,
- advance_commit_state_task_.callback(),
- begin_impl_frame_args_.interval * 2);
+ task_runner_->PostDelayedTask(FROM_HERE,
+ advance_commit_state_task_.callback(),
+ begin_impl_frame_args_.interval * 2);
}
} else {
advance_commit_state_task_.Cancel();
@@ -491,7 +494,7 @@ void Scheduler::PostBeginRetroFrameIfNeeded() {
return;
begin_retro_frame_posted_ = true;
- impl_task_runner_->PostTask(FROM_HERE, begin_retro_frame_closure_);
+ task_runner_->PostTask(FROM_HERE, begin_retro_frame_closure_);
}
// BeginImplFrame starts a compositor frame that will wait up until a deadline
@@ -499,8 +502,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(state_machine_.begin_impl_frame_state() ==
- SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
+ DCHECK_EQ(state_machine_.begin_impl_frame_state(),
+ SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
DCHECK(state_machine_.HasInitializedOutputSurface());
advance_commit_state_task_.Cancel();
@@ -567,7 +570,7 @@ void Scheduler::ScheduleBeginImplFrameDeadline(base::TimeTicks deadline) {
base::TimeDelta delta = deadline - gfx::FrameTime::Now();
if (delta <= base::TimeDelta())
delta = base::TimeDelta();
- impl_task_runner_->PostDelayedTask(
+ 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 afb9e9d..311a71d 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>& impl_task_runner) {
+ const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) {
return make_scoped_ptr(new Scheduler(
- client, scheduler_settings, layer_tree_host_id, impl_task_runner));
+ client, scheduler_settings, layer_tree_host_id, task_runner));
}
virtual ~Scheduler();
@@ -173,16 +173,15 @@ 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>& impl_task_runner);
+ Scheduler(SchedulerClient* client,
+ const SchedulerSettings& scheduler_settings,
+ int layer_tree_host_id,
+ const scoped_refptr<base::SingleThreadTaskRunner>& task_runner);
const SchedulerSettings settings_;
SchedulerClient* client_;
int layer_tree_host_id_;
- scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner_;
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
base::TimeDelta vsync_interval_;
base::TimeDelta estimated_parent_draw_time_;
diff --git a/cc/scheduler/scheduler_state_machine.cc b/cc/scheduler/scheduler_state_machine.cc
index a37a74a..723c40c 100644
--- a/cc/scheduler/scheduler_state_machine.cc
+++ b/cc/scheduler/scheduler_state_machine.cc
@@ -1006,7 +1006,9 @@ void SchedulerStateMachine::DidDrawIfPossibleCompleted(DrawResult result) {
}
}
-void SchedulerStateMachine::SetNeedsCommit() { needs_commit_ = true; }
+void SchedulerStateMachine::SetNeedsCommit() {
+ needs_commit_ = true;
+}
void SchedulerStateMachine::NotifyReadyToCommit() {
DCHECK(commit_state_ == COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED)
diff --git a/cc/test/fake_layer_tree_host_client.h b/cc/test/fake_layer_tree_host_client.h
index f928453..7f7bd35 100644
--- a/cc/test/fake_layer_tree_host_client.h
+++ b/cc/test/fake_layer_tree_host_client.h
@@ -42,8 +42,6 @@ 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 d72860d..312f643 100644
--- a/cc/test/layer_tree_test.cc
+++ b/cc/test/layer_tree_test.cc
@@ -312,14 +312,6 @@ 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 {}
@@ -394,7 +386,6 @@ 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),
@@ -558,15 +549,6 @@ 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_ && proxy()->CommitPendingForTesting()) {
main_task_runner_->PostTask(
@@ -618,16 +600,8 @@ void LayerTreeTest::DispatchSetNeedsRedrawRect(const gfx::Rect& damage_rect) {
void LayerTreeTest::DispatchSetVisible(bool visible) {
DCHECK(!proxy() || proxy()->IsMainThread());
-
- 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();
+ if (layer_tree_host_)
+ layer_tree_host_->SetVisible(visible);
}
void LayerTreeTest::DispatchSetNextCommitForcesRedraw() {
@@ -637,24 +611,6 @@ 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 8f38dda..619ae96 100644
--- a/cc/test/layer_tree_test.h
+++ b/cc/test/layer_tree_test.h
@@ -71,8 +71,6 @@ 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) {}
@@ -139,8 +137,6 @@ 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,
@@ -151,7 +147,6 @@ 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;
@@ -204,7 +199,6 @@ 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 ed7472d..03969f2 100644
--- a/cc/trees/layer_tree_host.cc
+++ b/cc/trees/layer_tree_host.cc
@@ -697,8 +697,12 @@ 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 70b2a64..4ddb1f2 100644
--- a/cc/trees/layer_tree_host_perftest.cc
+++ b/cc/trees/layer_tree_host_perftest.cc
@@ -228,6 +228,8 @@ 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 cb61450..dbca28c 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() = 0;
+ virtual void ScheduleComposite() {}
// Request that the client schedule a composite now, and calculate appropriate
// delay for potential future frame.
- virtual void ScheduleAnimation() = 0;
+ virtual void ScheduleAnimation() {}
// 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 2ddee12..453c75c 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_GE(1, num_commits_);
- EXPECT_GE(1, num_draws_);
+ EXPECT_LE(1, num_commits_);
+ EXPECT_LE(1, num_draws_);
}
private:
@@ -694,31 +694,6 @@ 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 {
@@ -1959,7 +1934,7 @@ class LayerTreeHostTestDeferCommits : public LayerTreeHostTest {
int num_complete_commits_;
};
-MULTI_THREAD_TEST_F(LayerTreeHostTestDeferCommits);
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestDeferCommits);
class LayerTreeHostWithProxy : public LayerTreeHost {
public:
@@ -2032,6 +2007,7 @@ 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());
@@ -2051,6 +2027,7 @@ 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());
@@ -2070,6 +2047,7 @@ 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());
@@ -2090,6 +2068,7 @@ TEST(LayerTreeHostTest,
LayerTreeSettings settings;
settings.max_partial_texture_updates = 4;
+ settings.single_thread_proxy_scheduler = false;
scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
new TestSharedBitmapManager());
@@ -4586,10 +4565,11 @@ class LayerTreeHostTestBreakSwapPromise : public LayerTreeHostTest {
// TODO(miletus): Flaky test: crbug.com/393995
// MULTI_THREAD_TEST_F(LayerTreeHostTestBreakSwapPromise);
-class LayerTreeHostTestBreakSwapPromiseForAbortedCommit
+class LayerTreeHostTestBreakSwapPromiseForVisibilityAbortedCommit
: public LayerTreeHostTest {
protected:
- LayerTreeHostTestBreakSwapPromiseForAbortedCommit() : commit_count_(0) {}
+ LayerTreeHostTestBreakSwapPromiseForVisibilityAbortedCommit()
+ : commit_count_(0) {}
virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
@@ -4628,7 +4608,54 @@ class LayerTreeHostTestBreakSwapPromiseForAbortedCommit
TestSwapPromiseResult swap_promise_result_;
};
-MULTI_THREAD_TEST_F(LayerTreeHostTestBreakSwapPromiseForAbortedCommit);
+SINGLE_AND_MULTI_THREAD_TEST_F(
+ LayerTreeHostTestBreakSwapPromiseForVisibilityAbortedCommit);
+
+class LayerTreeHostTestBreakSwapPromiseForContextAbortedCommit
+ : public LayerTreeHostTest {
+ protected:
+ LayerTreeHostTestBreakSwapPromiseForContextAbortedCommit()
+ : commit_count_(0) {}
+
+ virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
+
+ virtual void WillBeginMainFrame() OVERRIDE {
+ layer_tree_host()->SetDeferCommits(true);
+ layer_tree_host()->SetNeedsCommit();
+ }
+
+ virtual void DidDeferCommit() OVERRIDE {
+ layer_tree_host()->DidLoseOutputSurface();
+ layer_tree_host()->SetDeferCommits(false);
+
+ scoped_ptr<SwapPromise> swap_promise(
+ new TestSwapPromise(&swap_promise_result_));
+ layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
+ }
+
+ virtual void DidCommit() OVERRIDE { PostSetNeedsCommitToMainThread(); }
+
+ virtual void BeginMainFrameAbortedOnThread(LayerTreeHostImpl* host_impl,
+ bool did_handle) OVERRIDE {
+ EndTest();
+ }
+
+ 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);
+ }
+ }
+
+ int commit_count_;
+ TestSwapPromiseResult swap_promise_result_;
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(
+ LayerTreeHostTestBreakSwapPromiseForContextAbortedCommit);
class SimpleSwapPromiseMonitor : public SwapPromiseMonitor {
public:
@@ -4708,7 +4735,7 @@ class LayerTreeHostTestSimpleSwapPromiseMonitor : public LayerTreeHostTest {
virtual void AfterTest() OVERRIDE {}
};
-MULTI_THREAD_TEST_F(LayerTreeHostTestSimpleSwapPromiseMonitor);
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSimpleSwapPromiseMonitor);
class LayerTreeHostTestHighResRequiredAfterEvictingUIResources
: public LayerTreeHostTest {
diff --git a/cc/trees/layer_tree_host_unittest_animation.cc b/cc/trees/layer_tree_host_unittest_animation.cc
index f717c2a..1853bfc 100644
--- a/cc/trees/layer_tree_host_unittest_animation.cc
+++ b/cc/trees/layer_tree_host_unittest_animation.cc
@@ -726,9 +726,7 @@ class LayerTreeHostAnimationTestContinuousAnimate
: public LayerTreeHostAnimationTest {
public:
LayerTreeHostAnimationTestContinuousAnimate()
- : num_commit_complete_(0),
- num_draw_layers_(0) {
- }
+ : num_commit_complete_(0), num_draw_layers_(0), have_animated_(false) {}
virtual void SetupTree() OVERRIDE {
LayerTreeHostAnimationTest::SetupTree();
@@ -747,6 +745,7 @@ class LayerTreeHostAnimationTestContinuousAnimate
if (num_draw_layers_ == 2)
return;
layer_tree_host()->SetNeedsAnimate();
+ have_animated_ = true;
}
virtual void Layout() OVERRIDE {
@@ -767,16 +766,18 @@ class LayerTreeHostAnimationTestContinuousAnimate
virtual void AfterTest() OVERRIDE {
// Check that we didn't commit twice between first and second draw.
EXPECT_EQ(1, num_commit_complete_);
+ EXPECT_TRUE(have_animated_);
}
private:
int num_commit_complete_;
int num_draw_layers_;
+ bool have_animated_;
FakeContentLayerClient client_;
scoped_refptr<FakeContentLayer> content_;
};
-MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestContinuousAnimate);
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestContinuousAnimate);
class LayerTreeHostAnimationTestCancelAnimateCommit
: public LayerTreeHostAnimationTest {
diff --git a/cc/trees/layer_tree_host_unittest_context.cc b/cc/trees/layer_tree_host_unittest_context.cc
index 80898d2..887e603 100644
--- a/cc/trees/layer_tree_host_unittest_context.cc
+++ b/cc/trees/layer_tree_host_unittest_context.cc
@@ -65,6 +65,9 @@ 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;
@@ -200,45 +203,53 @@ class LayerTreeHostContextTestLostContextSucceeds
static const TestCase kTests[] = {
// Losing the context and failing to recreate it (or losing it again
// immediately) a small number of times should succeed.
- {1, // times_to_lose_during_commit
+ {
+ 1, // times_to_lose_during_commit
0, // times_to_lose_during_draw
0, // times_to_fail_recreate
false, // fallback_context_works
},
- {0, // times_to_lose_during_commit
+ {
+ 0, // times_to_lose_during_commit
1, // times_to_lose_during_draw
0, // times_to_fail_recreate
false, // fallback_context_works
},
- {1, // times_to_lose_during_commit
+ {
+ 1, // times_to_lose_during_commit
0, // times_to_lose_during_draw
3, // times_to_fail_recreate
false, // fallback_context_works
},
- {0, // times_to_lose_during_commit
+ {
+ 0, // times_to_lose_during_commit
1, // times_to_lose_during_draw
3, // times_to_fail_recreate
false, // fallback_context_works
},
// Losing the context and recreating it any number of times should
// succeed.
- {10, // times_to_lose_during_commit
+ {
+ 10, // times_to_lose_during_commit
0, // times_to_lose_during_draw
0, // times_to_fail_recreate
false, // fallback_context_works
},
- {0, // times_to_lose_during_commit
+ {
+ 0, // times_to_lose_during_commit
10, // times_to_lose_during_draw
0, // times_to_fail_recreate
false, // fallback_context_works
},
// Losing the context, failing to reinitialize it, and making a fallback
// context should work.
- {0, // times_to_lose_during_commit
+ {
+ 0, // times_to_lose_during_commit
1, // times_to_lose_during_draw
0, // times_to_fail_recreate
true, // fallback_context_works
- }, };
+ },
+ };
if (test_case_ >= arraysize(kTests))
return false;
@@ -300,7 +311,8 @@ class LayerTreeHostClientNotReadyDoesNotCreateOutputSurface
}
};
-MULTI_THREAD_TEST_F(LayerTreeHostClientNotReadyDoesNotCreateOutputSurface);
+SINGLE_AND_MULTI_THREAD_TEST_F(
+ LayerTreeHostClientNotReadyDoesNotCreateOutputSurface);
class LayerTreeHostContextTestLostContextSucceedsWithContent
: public LayerTreeHostContextTestLostContextSucceeds {
@@ -358,10 +370,11 @@ class LayerTreeHostContextTestCreateOutputSurfaceFails
: times_to_fail_(times_to_fail),
expect_fallback_attempt_(expect_fallback_attempt),
did_attempt_fallback_(false),
- times_initialized_(0) {}
+ times_initialized_(0) {
+ times_to_fail_create_ = times_to_fail_;
+ }
virtual void BeginTest() OVERRIDE {
- times_to_fail_create_ = times_to_fail_;
PostSetNeedsCommitToMainThread();
}
@@ -975,12 +988,6 @@ 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();
}
@@ -1024,12 +1031,10 @@ class UIResourceLostTest : public LayerTreeHostContextTest {
void PostLoseContextToImplThread() {
EXPECT_TRUE(layer_tree_host()->proxy()->IsMainThread());
- base::SingleThreadTaskRunner* task_runner =
- HasImplThread() ? ImplThreadTaskRunner()
- : base::MessageLoopProxy::current();
- task_runner->PostTask(FROM_HERE,
- base::Bind(&LayerTreeHostContextTest::LoseContext,
- base::Unretained(this)));
+ ImplThreadTaskRunner()->PostTask(
+ FROM_HERE,
+ base::Bind(&LayerTreeHostContextTest::LoseContext,
+ base::Unretained(this)));
}
protected:
@@ -1084,13 +1089,8 @@ class UIResourceLostAfterCommit : public UIResourceLostTestSimple {
EndTest();
break;
case 5:
- // Single thread proxy issues extra commits after context lost.
- // http://crbug.com/287250
- if (HasImplThread())
- NOTREACHED();
- break;
- case 6:
NOTREACHED();
+ break;
}
}
@@ -1178,13 +1178,8 @@ class UIResourceLostBeforeCommit : public UIResourceLostTestSimple {
EndTest();
break;
case 6:
- // Single thread proxy issues extra commits after context lost.
- // http://crbug.com/287250
- if (HasImplThread())
- NOTREACHED();
- break;
- case 8:
NOTREACHED();
+ break;
}
}
@@ -1205,15 +1200,8 @@ class UIResourceLostBeforeCommit : public UIResourceLostTestSimple {
// Sequence 2 (continued):
// The previous resource should have been deleted.
EXPECT_EQ(0u, impl->ResourceIdForUIResource(test_id0_));
- 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 should have been created.
+ EXPECT_NE(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);
@@ -1529,8 +1517,8 @@ class LayerTreeHostContextTestLoseAfterSendingBeginMainFrame
bool deferred_;
};
-// TODO(danakj): We don't use scheduler with SingleThreadProxy yet.
-MULTI_THREAD_TEST_F(LayerTreeHostContextTestLoseAfterSendingBeginMainFrame);
+SINGLE_AND_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 1a24ba5..ea3bfc6 100644
--- a/cc/trees/layer_tree_host_unittest_no_message_loop.cc
+++ b/cc/trees/layer_tree_host_unittest_no_message_loop.cc
@@ -74,8 +74,6 @@ class LayerTreeHostNoMessageLoopTest
virtual void DidCompleteSwapBuffers() OVERRIDE {}
// LayerTreeHostSingleThreadClient overrides.
- virtual void ScheduleComposite() OVERRIDE {}
- virtual void ScheduleAnimation() OVERRIDE {}
virtual void DidPostSwapBuffers() OVERRIDE {}
virtual void DidAbortSwapBuffers() OVERRIDE {}
@@ -96,6 +94,7 @@ 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 bf72893..56e18a2 100644
--- a/cc/trees/layer_tree_settings.cc
+++ b/cc/trees/layer_tree_settings.cc
@@ -16,6 +16,7 @@ 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 14cec67..bad3bf4 100644
--- a/cc/trees/layer_tree_settings.h
+++ b/cc/trees/layer_tree_settings.h
@@ -21,6 +21,7 @@ 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
new file mode 100644
index 0000000..f8dfc01
--- /dev/null
+++ b/cc/trees/scoped_abort_remaining_swap_promises.h
@@ -0,0 +1,30 @@
+// 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 2f67740..24e5e2a 100644
--- a/cc/trees/single_thread_proxy.cc
+++ b/cc/trees/single_thread_proxy.cc
@@ -16,6 +16,7 @@
#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 {
@@ -36,8 +37,13 @@ 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) {
+ inside_draw_(false),
+ defer_commits_(false),
+ commit_was_deferred_(false),
+ commit_requested_(false),
+ weak_factory_(this) {
TRACE_EVENT0("cc", "SingleThreadProxy::SingleThreadProxy");
DCHECK(Proxy::IsMainThread());
DCHECK(layer_tree_host);
@@ -77,13 +83,26 @@ 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();
}
@@ -110,9 +129,14 @@ void SingleThreadProxy::CreateAndInitializeOutputSurface() {
layer_tree_host_->OnCreateAndInitializeOutputSurfaceAttempted(success);
- if (!success) {
- // Force another recreation attempt to happen by requesting another commit.
- SetNeedsCommit();
+ 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()));
}
}
@@ -126,17 +150,40 @@ 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());
- client_->ScheduleComposite();
+ SetNeedsCommit();
}
-void SingleThreadProxy::DoCommit(scoped_ptr<ResourceUpdateQueue> queue) {
+void SingleThreadProxy::DoCommit(base::TimeTicks frame_begin_time) {
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);
@@ -158,7 +205,7 @@ void SingleThreadProxy::DoCommit(scoped_ptr<ResourceUpdateQueue> queue) {
scoped_ptr<ResourceUpdateController> update_controller =
ResourceUpdateController::Create(
NULL,
- Proxy::MainThreadTaskRunner(),
+ MainThreadTaskRunner(),
queue.Pass(),
layer_tree_host_impl_->resource_provider());
update_controller->Finalize();
@@ -170,6 +217,8 @@ void SingleThreadProxy::DoCommit(scoped_ptr<ResourceUpdateQueue> queue) {
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.
@@ -186,30 +235,63 @@ void SingleThreadProxy::DoCommit(scoped_ptr<ResourceUpdateQueue> queue) {
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");
- SetNeedsRedrawRectOnImplThread(damage_rect);
+ DCHECK(Proxy::IsMainThread());
+ DebugScopedSetImplThread impl(this);
client_->ScheduleComposite();
+ SetNeedsRedrawRectOnImplThread(damage_rect);
}
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 { return false; }
+bool SingleThreadProxy::CommitRequested() const {
+ DCHECK(Proxy::IsMainThread());
+ return commit_requested_;
+}
-bool SingleThreadProxy::BeginMainFrameRequested() const { return false; }
+bool SingleThreadProxy::BeginMainFrameRequested() const {
+ DCHECK(Proxy::IsMainThread());
+ return commit_requested_;
+}
size_t SingleThreadProxy::MaxPartialTextureUpdates() const {
return std::numeric_limits<size_t>::max();
@@ -225,6 +307,7 @@ 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;
@@ -235,15 +318,19 @@ 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() {
- // Thread-only feature.
+ // Impl-side painting only.
NOTREACHED();
}
void SingleThreadProxy::SetNeedsRedrawOnImplThread() {
client_->ScheduleComposite();
+ if (scheduler_on_impl_thread_)
+ scheduler_on_impl_thread_->SetNeedsRedraw();
}
void SingleThreadProxy::SetNeedsAnimateOnImplThread() {
@@ -251,17 +338,14 @@ void SingleThreadProxy::SetNeedsAnimateOnImplThread() {
}
void SingleThreadProxy::SetNeedsManageTilesOnImplThread() {
- // Thread-only/Impl-side-painting-only feature.
+ // Impl-side painting only.
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);
- SetNeedsCommit();
+ SetNeedsRedrawOnImplThread();
}
void SingleThreadProxy::DidInitializeVisibleTileOnImplThread() {
@@ -271,6 +355,8 @@ void SingleThreadProxy::DidInitializeVisibleTileOnImplThread() {
void SingleThreadProxy::SetNeedsCommitOnImplThread() {
client_->ScheduleComposite();
+ if (scheduler_on_impl_thread_)
+ scheduler_on_impl_thread_->SetNeedsCommit();
}
void SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread(
@@ -307,66 +393,53 @@ 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");
- // Cause a commit so we can notice the lost context.
- SetNeedsCommitOnImplThread();
+ {
+ 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();
+ }
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");
- client_->DidCompleteSwapBuffers();
+ 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);
}
-// 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());
- 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();
+ DoCommit(frame_begin_time);
LayerTreeHostImpl::FrameData 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();
- }
+ DoComposite(frame_begin_time, &frame);
}
void SingleThreadProxy::AsValueInto(base::debug::TracedValue* state) const {
@@ -406,13 +479,11 @@ void SingleThreadProxy::UpdateBackgroundAnimateTicking() {
!ShouldComposite() && layer_tree_host_impl_->active_tree()->root_layer());
}
-bool SingleThreadProxy::DoComposite(
- base::TimeTicks frame_begin_time,
- LayerTreeHostImpl::FrameData* frame) {
+DrawResult 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);
@@ -423,9 +494,11 @@ bool SingleThreadProxy::DoComposite(
// CanDraw() as well.
if (!ShouldComposite()) {
UpdateBackgroundAnimateTicking();
- return false;
+ return DRAW_ABORTED_CANT_DRAW;
}
+ timing_history_.DidStartDrawing();
+
layer_tree_host_impl_->Animate(
layer_tree_host_impl_->CurrentFrameTimeTicks());
UpdateBackgroundAnimateTicking();
@@ -435,24 +508,43 @@ bool SingleThreadProxy::DoComposite(
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();
}
- if (lost_output_surface) {
- layer_tree_host_->DidLoseOutputSurface();
- return false;
+ {
+ 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);
+ }
}
+ DidCommitAndDrawFrame();
- return true;
+ return DRAW_SUCCESS;
}
-void SingleThreadProxy::DidSwapFrame() {
+void SingleThreadProxy::DidCommitAndDrawFrame() {
if (next_frame_is_newly_committed_frame_) {
+ DebugScopedSetMainThread main(this);
next_frame_is_newly_committed_frame_ = false;
layer_tree_host_->DidCommitAndDrawFrame();
}
@@ -460,4 +552,146 @@ void SingleThreadProxy::DidSwapFrame() {
bool SingleThreadProxy::CommitPendingForTesting() { 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 2b70d70..0582f1e 100644
--- a/cc/trees/single_thread_proxy.h
+++ b/cc/trees/single_thread_proxy.h
@@ -10,8 +10,10 @@
#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 {
@@ -20,7 +22,8 @@ class LayerTreeHost;
class LayerTreeHostSingleThreadClient;
class CC_EXPORT SingleThreadProxy : public Proxy,
- NON_EXPORTED_BASE(LayerTreeHostImplClient) {
+ NON_EXPORTED_BASE(LayerTreeHostImplClient),
+ SchedulerClient {
public:
static scoped_ptr<Proxy> Create(
LayerTreeHost* layer_tree_host,
@@ -52,6 +55,24 @@ class CC_EXPORT SingleThreadProxy : public Proxy,
virtual void AsValueInto(base::debug::TracedValue* state) const OVERRIDE;
virtual bool CommitPendingForTesting() 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;
@@ -61,7 +82,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;
@@ -82,7 +103,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
@@ -98,10 +119,13 @@ class CC_EXPORT SingleThreadProxy : public Proxy,
LayerTreeHostSingleThreadClient* client,
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner);
- void DoCommit(scoped_ptr<ResourceUpdateQueue> queue);
- bool DoComposite(base::TimeTicks frame_begin_time,
- LayerTreeHostImpl::FrameData* frame);
- void DidSwapFrame();
+ 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();
bool ShouldComposite() const;
void UpdateBackgroundAnimateTicking();
@@ -115,9 +139,18 @@ 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 a379d0e..d5301ee 100644
--- a/cc/trees/thread_proxy.cc
+++ b/cc/trees/thread_proxy.cc
@@ -25,6 +25,7 @@
#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"
@@ -37,19 +38,6 @@ 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::CommitPendingRequest {
@@ -458,9 +446,10 @@ void ThreadProxy::SetNextCommitWaitsForActivation() {
void ThreadProxy::SetDeferCommits(bool defer_commits) {
DCHECK(IsMainThread());
- DCHECK_NE(main().defer_commits, defer_commits);
- main().defer_commits = defer_commits;
+ if (main().defer_commits == defer_commits)
+ return;
+ main().defer_commits = defer_commits;
if (main().defer_commits)
TRACE_EVENT_ASYNC_BEGIN0("cc", "ThreadProxy::SetDeferCommits", this);
else
@@ -740,9 +729,9 @@ void ThreadProxy::BeginMainFrame(
}
// If the commit finishes, LayerTreeHost will transfer its swap promises to
- // LayerTreeImpl. The destructor of SwapPromiseChecker checks LayerTressHost's
- // swap promises.
- SwapPromiseChecker swap_promise_checker(layer_tree_host());
+ // LayerTreeImpl. The destructor of ScopedSwapPromiseChecker aborts the
+ // remaining swap promises.
+ ScopedAbortRemainingSwapPromises 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 4e9c4ae..7fb4ec8 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,8 +17,9 @@ 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. crbug.com/163931
-#if defined(OS_LINUX) && defined(USE_AURA)
+// 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)
#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 3ca74a2..13b0735 100644
--- a/content/browser/renderer_host/compositor_impl_android.cc
+++ b/content/browser/renderer_host/compositor_impl_android.cc
@@ -314,7 +314,6 @@ 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_) {
@@ -426,7 +425,6 @@ 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;
@@ -441,6 +439,8 @@ 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,10 +523,9 @@ CreateGpuProcessViewContext(
}
void CompositorImpl::Layout() {
- // TODO: If we get this callback from the SingleThreadProxy, we need
- // to stop calling it ourselves in CompositorImpl::Composite().
- NOTREACHED();
+ ignore_schedule_composite_ = true;
client_->Layout();
+ ignore_schedule_composite_ = false;
}
scoped_ptr<cc::OutputSurface> CompositorImpl::CreateOutputSurface(
@@ -575,7 +574,6 @@ void CompositorImpl::ScheduleComposite() {
}
void CompositorImpl::ScheduleAnimation() {
- DCHECK(!needs_animate_ || needs_composite_);
DCHECK(!needs_composite_ || WillComposite());
needs_animate_ = true;
@@ -605,6 +603,7 @@ 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 a9cf52f..1144516 100644
--- a/content/public/common/content_switches.cc
+++ b/content/public/common/content_switches.cc
@@ -246,6 +246,10 @@ 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";
+
// Disables site-specific tailoring to compatibility issues in WebKit.
const char kDisableSiteSpecificQuirks[] = "disable-site-specific-quirks";
diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h
index 8a19213..908e544 100644
--- a/content/public/common/content_switches.h
+++ b/content/public/common/content_switches.h
@@ -79,6 +79,7 @@ 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[];
extern const char kDisableSiteSpecificQuirks[];
CONTENT_EXPORT extern const char kDisableSmoothScrolling[];
CONTENT_EXPORT extern const char kDisableSoftwareRasterizer[];
diff --git a/content/renderer/gpu/render_widget_compositor.cc b/content/renderer/gpu/render_widget_compositor.cc
index 64e0982..baf1ac1 100644
--- a/content/renderer/gpu/render_widget_compositor.cc
+++ b/content/renderer/gpu/render_widget_compositor.cc
@@ -277,6 +277,8 @@ 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 =
@@ -409,7 +411,6 @@ scoped_ptr<RenderWidgetCompositor> RenderWidgetCompositor::Create(
RenderWidgetCompositor::RenderWidgetCompositor(RenderWidget* widget,
bool threaded)
: threaded_(threaded),
- suppress_schedule_composite_(false),
widget_(widget) {
}
@@ -420,27 +421,10 @@ 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();
}
@@ -549,7 +533,10 @@ void RenderWidgetCompositor::Initialize(cc::LayerTreeSettings settings) {
}
void RenderWidgetCompositor::setSurfaceReady() {
- layer_tree_host_->SetLayerTreeHostClientReady();
+ // 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();
}
void RenderWidgetCompositor::setRootLayer(const blink::WebLayer& layer) {
@@ -702,9 +689,9 @@ void RenderWidgetCompositor::compositeAndReadbackAsync(
cc::CopyOutputRequest::CreateBitmapRequest(
base::Bind(&CompositeAndReadbackAsyncCallback, callback));
layer_tree_host_->root_layer()->RequestCopyOfOutput(request.Pass());
- if (!threaded_) {
- widget_->webwidget()->animate(0.0);
- widget_->webwidget()->layout();
+
+ if (!threaded_ &&
+ !layer_tree_host_->settings().single_thread_proxy_scheduler) {
layer_tree_host_->Composite(gfx::FrameTime::Now());
}
}
@@ -800,11 +787,6 @@ 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 e0541ec..79a03b4 100644
--- a/content/renderer/gpu/render_widget_compositor.h
+++ b/content/renderer/gpu/render_widget_compositor.h
@@ -44,9 +44,7 @@ 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,
@@ -143,7 +141,6 @@ 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;
@@ -154,7 +151,6 @@ 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 10d87e1..7e7fb2d 100644
--- a/content/renderer/render_widget.cc
+++ b/content/renderer/render_widget.cc
@@ -393,6 +393,7 @@ 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),
@@ -1201,6 +1202,8 @@ void RenderWidget::AutoResizeCompositor() {
}
void RenderWidget::initializeLayerTreeView() {
+ DCHECK(!host_closing_);
+
compositor_ =
RenderWidgetCompositor::Create(this, IsThreadedCompositingEnabled());
compositor_->setViewportSize(size_, physical_backing_size_);
@@ -1208,20 +1211,20 @@ void RenderWidget::initializeLayerTreeView() {
StartCompositor();
}
-blink::WebLayerTreeView* RenderWidget::layerTreeView() {
- return compositor_.get();
+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();
}
-void RenderWidget::suppressCompositorScheduling(bool enable) {
- if (compositor_)
- compositor_->SetSuppressScheduleComposite(enable);
+blink::WebLayerTreeView* RenderWidget::layerTreeView() {
+ return compositor_.get();
}
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.
@@ -1378,6 +1381,12 @@ 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_));
}
@@ -1418,8 +1427,7 @@ void RenderWidget::QueueSyntheticGesture(
void RenderWidget::Close() {
screen_metrics_emulator_.reset();
if (webwidget_) {
- webwidget_->willCloseLayerTreeView();
- compositor_.reset();
+ DestroyLayerTreeView();
webwidget_->close();
webwidget_ = NULL;
}
diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h
index bd97588..22612a5 100644
--- a/content/renderer/render_widget.h
+++ b/content/renderer/render_widget.h
@@ -142,7 +142,6 @@ 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();
@@ -173,6 +172,9 @@ 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);
@@ -624,6 +626,9 @@ 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 7e36976..18086de 100644
--- a/content/shell/renderer/test_runner/web_test_proxy.cc
+++ b/content/shell/renderer/test_runner/web_test_proxy.cc
@@ -7,9 +7,11 @@
#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"
@@ -313,6 +315,10 @@ 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 13d6ee4..730c210 100644
--- a/content/test/web_layer_tree_view_impl_for_testing.h
+++ b/content/test/web_layer_tree_view_impl_for_testing.h
@@ -80,8 +80,6 @@ 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 14b5366..6be8530 100644
--- a/ui/compositor/compositor.cc
+++ b/ui/compositor/compositor.cc
@@ -61,14 +61,6 @@ 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)
@@ -79,16 +71,9 @@ 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),
- 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) {
+ layer_animator_collection_(this) {
root_web_layer_ = cc::Layer::Create();
CommandLine* command_line = CommandLine::ForCurrentProcess();
@@ -177,14 +162,7 @@ Compositor::~Compositor() {
}
void Compositor::ScheduleDraw() {
- 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()));
- }
+ host_->SetNeedsCommit();
}
void Compositor::SetRootLayer(Layer* root_layer) {
@@ -205,42 +183,19 @@ 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() {
@@ -347,45 +302,30 @@ 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_) {
- NotifyEnd();
- } else {
- DCHECK_EQ(swap_state_, SWAP_POSTED);
- NotifyEnd();
- swap_state_ = SWAP_COMPLETED;
+ base::TimeTicks start_time = gfx::FrameTime::Now();
+ FOR_EACH_OBSERVER(CompositorObserver,
+ observer_list_,
+ OnCompositingStarted(this, start_time));
}
-}
-
-void Compositor::ScheduleComposite() {
- if (!disable_schedule_composite_)
- ScheduleDraw();
-}
-
-void Compositor::ScheduleAnimation() {
- ScheduleComposite();
+ FOR_EACH_OBSERVER(
+ CompositorObserver, observer_list_, OnCompositingEnded(this));
}
void Compositor::DidPostSwapBuffers() {
- DCHECK(!compositor_thread_loop_);
- DCHECK_EQ(swap_state_, SWAP_NONE);
- swap_state_ = SWAP_POSTED;
+ base::TimeTicks start_time = gfx::FrameTime::Now();
+ FOR_EACH_OBSERVER(CompositorObserver,
+ observer_list_,
+ OnCompositingStarted(this, start_time));
}
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));
@@ -403,8 +343,7 @@ void Compositor::SetLayerTreeDebugState(
scoped_refptr<CompositorLock> Compositor::GetCompositorLock() {
if (!compositor_lock_) {
compositor_lock_ = new CompositorLock(this);
- if (compositor_thread_loop_)
- host_->SetDeferCommits(true);
+ host_->SetDeferCommits(true);
FOR_EACH_OBSERVER(CompositorObserver,
observer_list_,
OnCompositingLockStateChanged(this));
@@ -415,8 +354,7 @@ scoped_refptr<CompositorLock> Compositor::GetCompositorLock() {
void Compositor::UnlockCompositor() {
DCHECK(compositor_lock_);
compositor_lock_ = NULL;
- if (compositor_thread_loop_)
- host_->SetDeferCommits(false);
+ host_->SetDeferCommits(false);
FOR_EACH_OBSERVER(CompositorObserver,
observer_list_,
OnCompositingLockStateChanged(this));
@@ -427,21 +365,4 @@ 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 0e4ac8a..b2d2779 100644
--- a/ui/compositor/compositor.h
+++ b/ui/compositor/compositor.h
@@ -24,8 +24,6 @@
#include "ui/gfx/size.h"
#include "ui/gfx/vector2d.h"
-class SkBitmap;
-
namespace base {
class MessageLoopProxy;
class RunLoop;
@@ -159,9 +157,6 @@ 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.
@@ -234,14 +229,9 @@ 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;
@@ -261,9 +251,6 @@ 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_;
@@ -294,19 +281,8 @@ 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 ac1a47b..b5c473c 100644
--- a/ui/compositor/layer_unittest.cc
+++ b/ui/compositor/layer_unittest.cc
@@ -95,8 +95,8 @@ class LayerWithRealCompositorTest : public testing::Test {
InitializeContextFactoryForTests(enable_pixel_output);
const gfx::Rect host_bounds(10, 10, 500, 500);
- compositor_host_.reset(TestCompositorHost::Create(
- host_bounds, context_factory));
+ compositor_host_.reset(
+ TestCompositorHost::Create(host_bounds, context_factory));
compositor_host_->Show();
}
@@ -126,7 +126,7 @@ class LayerWithRealCompositorTest : public testing::Test {
void DrawTree(Layer* root) {
GetCompositor()->SetRootLayer(root);
GetCompositor()->ScheduleDraw();
- WaitForDraw();
+ WaitForSwap();
}
bool ReadPixels(SkBitmap* bitmap) {
@@ -142,11 +142,13 @@ class LayerWithRealCompositorTest : public testing::Test {
GetCompositor()->root_layer()->RequestCopyOfOutput(request.Pass());
- // 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();
+ // 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();
WaitForDraw();
}
@@ -161,7 +163,11 @@ class LayerWithRealCompositorTest : public testing::Test {
}
void WaitForDraw() {
- ui::DrawWaiterForTest::Wait(GetCompositor());
+ ui::DrawWaiterForTest::WaitForCompositingStarted(GetCompositor());
+ }
+
+ void WaitForSwap() {
+ DrawWaiterForTest::WaitForCompositingEnded(GetCompositor());
}
void WaitForCommit() {
@@ -450,7 +456,7 @@ class LayerWithDelegateTest : public testing::Test {
}
void WaitForDraw() {
- DrawWaiterForTest::Wait(compositor());
+ DrawWaiterForTest::WaitForCompositingStarted(compositor());
}
void WaitForCommit() {
@@ -945,25 +951,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));
- WaitForDraw();
+ WaitForSwap();
EXPECT_TRUE(observer.notified());
// So should resizing a layer.
observer.Reset();
l2->SetBounds(gfx::Rect(0, 0, 400, 400));
- WaitForDraw();
+ WaitForSwap();
EXPECT_TRUE(observer.notified());
// Opacity changes should alert the observers.
observer.Reset();
l2->SetOpacity(0.5f);
- WaitForDraw();
+ WaitForSwap();
EXPECT_TRUE(observer.notified());
// So should setting the opacity back.
observer.Reset();
l2->SetOpacity(1.0f);
- WaitForDraw();
+ WaitForSwap();
EXPECT_TRUE(observer.notified());
// Setting the transform of a layer should alert the observers.
@@ -973,7 +979,7 @@ TEST_F(LayerWithRealCompositorTest, CompositorObservers) {
transform.Rotate(90.0);
transform.Translate(-200.0, -200.0);
l2->SetTransform(transform);
- WaitForDraw();
+ WaitForSwap();
EXPECT_TRUE(observer.notified());
// A change resulting in an aborted swap buffer should alert the observer
@@ -981,7 +987,7 @@ TEST_F(LayerWithRealCompositorTest, CompositorObservers) {
observer.Reset();
l2->SetOpacity(0.1f);
GetCompositor()->DidAbortSwapBuffers();
- WaitForDraw();
+ WaitForSwap();
EXPECT_TRUE(observer.notified());
EXPECT_TRUE(observer.aborted());
@@ -990,7 +996,7 @@ TEST_F(LayerWithRealCompositorTest, CompositorObservers) {
// Opacity changes should no longer alert the removed observer.
observer.Reset();
l2->SetOpacity(0.5f);
- WaitForDraw();
+ WaitForSwap();
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 c471a6f..f256ecc 100644
--- a/ui/compositor/test/draw_waiter_for_test.cc
+++ b/ui/compositor/test/draw_waiter_for_test.cc
@@ -9,20 +9,25 @@
namespace ui {
// static
-void DrawWaiterForTest::Wait(Compositor* compositor) {
- DrawWaiterForTest waiter;
- waiter.wait_for_commit_ = false;
+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);
waiter.WaitImpl(compositor);
}
// static
void DrawWaiterForTest::WaitForCommit(Compositor* compositor) {
- DrawWaiterForTest waiter;
- waiter.wait_for_commit_ = true;
+ DrawWaiterForTest waiter(WAIT_FOR_COMMIT);
waiter.WaitImpl(compositor);
}
-DrawWaiterForTest::DrawWaiterForTest() {}
+DrawWaiterForTest::DrawWaiterForTest(WaitEvent wait_event)
+ : wait_event_(wait_event) {
+}
DrawWaiterForTest::~DrawWaiterForTest() {}
@@ -34,19 +39,23 @@ void DrawWaiterForTest::WaitImpl(Compositor* compositor) {
}
void DrawWaiterForTest::OnCompositingDidCommit(Compositor* compositor) {
- if (wait_for_commit_)
+ if (wait_event_ == WAIT_FOR_COMMIT)
wait_run_loop_->Quit();
}
void DrawWaiterForTest::OnCompositingStarted(Compositor* compositor,
- base::TimeTicks start_time) {}
+ base::TimeTicks start_time) {
+ if (wait_event_ == WAIT_FOR_COMPOSITING_STARTED)
+ wait_run_loop_->Quit();
+}
void DrawWaiterForTest::OnCompositingEnded(Compositor* compositor) {
- if (!wait_for_commit_)
+ if (wait_event_ == WAIT_FOR_COMPOSITING_ENDED)
wait_run_loop_->Quit();
}
-void DrawWaiterForTest::OnCompositingAborted(Compositor* compositor) {}
+void DrawWaiterForTest::OnCompositingAborted(Compositor* compositor) {
+}
void DrawWaiterForTest::OnCompositingLockStateChanged(Compositor* compositor) {}
diff --git a/ui/compositor/test/draw_waiter_for_test.h b/ui/compositor/test/draw_waiter_for_test.h
index 051c58f..e1d63ff 100644
--- a/ui/compositor/test/draw_waiter_for_test.h
+++ b/ui/compositor/test/draw_waiter_for_test.h
@@ -20,13 +20,22 @@ 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 Wait(Compositor* compositor);
+ static void WaitForCompositingStarted(Compositor* compositor);
+
+ // Waits for a swap to be completed from the compositor.
+ static void WaitForCompositingEnded(Compositor* compositor);
// Waits for a commit instead of a draw.
static void WaitForCommit(Compositor* compositor);
private:
- DrawWaiterForTest();
+ enum WaitEvent {
+ WAIT_FOR_COMMIT,
+ WAIT_FOR_COMPOSITING_STARTED,
+ WAIT_FOR_COMPOSITING_ENDED,
+ };
+
+ DrawWaiterForTest(WaitEvent wait_event);
virtual ~DrawWaiterForTest();
void WaitImpl(Compositor* compositor);
@@ -41,7 +50,7 @@ class DrawWaiterForTest : public CompositorObserver {
scoped_ptr<base::RunLoop> wait_run_loop_;
- bool wait_for_commit_;
+ WaitEvent wait_event_;
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 8d533d0..7201fde 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_->Draw();
+ compositor_->ScheduleFullRedraw();
}
@end
diff --git a/ui/compositor/test/test_compositor_host_ozone.cc b/ui/compositor/test/test_compositor_host_ozone.cc
index 1c4b0cc..903c3b6 100644
--- a/ui/compositor/test/test_compositor_host_ozone.cc
+++ b/ui/compositor/test/test_compositor_host_ozone.cc
@@ -27,8 +27,6 @@ class TestCompositorHostOzone : public TestCompositorHost {
virtual void Show() OVERRIDE;
virtual ui::Compositor* GetCompositor() OVERRIDE;
- void Draw();
-
gfx::Rect bounds_;
ui::ContextFactory* context_factory_;
@@ -64,11 +62,6 @@ 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 9c732f6..80db4ae 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_->Draw();
+ compositor_->ScheduleFullRedraw();
ValidateRect(hwnd(), NULL);
}
diff --git a/ui/compositor/test/test_compositor_host_x11.cc b/ui/compositor/test/test_compositor_host_x11.cc
index 9b2d265..1c3f674 100644
--- a/ui/compositor/test/test_compositor_host_x11.cc
+++ b/ui/compositor/test/test_compositor_host_x11.cc
@@ -30,8 +30,6 @@ class TestCompositorHostX11 : public TestCompositorHost {
virtual void Show() OVERRIDE;
virtual ui::Compositor* GetCompositor() OVERRIDE;
- void Draw();
-
gfx::Rect bounds_;
ui::ContextFactory* context_factory_;
@@ -85,11 +83,6 @@ 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 5fe05a8..018394b 100644
--- a/ui/snapshot/snapshot_aura_unittest.cc
+++ b/ui/snapshot/snapshot_aura_unittest.cc
@@ -115,7 +115,8 @@ class SnapshotAuraTest : public testing::Test {
void WaitForDraw() {
helper_->host()->compositor()->ScheduleDraw();
- ui::DrawWaiterForTest::Wait(helper_->host()->compositor());
+ ui::DrawWaiterForTest::WaitForCompositingEnded(
+ 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 c4e6dcb..87164b0 100644
--- a/ui/views/view_unittest.cc
+++ b/ui/views/view_unittest.cc
@@ -3087,20 +3087,23 @@ TEST_F(ViewLayerTest, DontPaintChildrenWithLayers) {
widget()->SetContentsView(content_view);
content_view->SetPaintToLayer(true);
GetRootLayer()->GetCompositor()->ScheduleDraw();
- ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor());
+ ui::DrawWaiterForTest::WaitForCompositingEnded(
+ 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::Wait(GetRootLayer()->GetCompositor());
+ ui::DrawWaiterForTest::WaitForCompositingEnded(
+ 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::Wait(GetRootLayer()->GetCompositor());
+ ui::DrawWaiterForTest::WaitForCompositingEnded(
+ GetRootLayer()->GetCompositor());
EXPECT_TRUE(content_view->painted());
}
@@ -3340,13 +3343,15 @@ 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::Wait(GetRootLayer()->GetCompositor());
+ ui::DrawWaiterForTest::WaitForCompositingEnded(
+ 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::Wait(GetRootLayer()->GetCompositor());
+ ui::DrawWaiterForTest::WaitForCompositingEnded(
+ 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));
@@ -3354,7 +3359,8 @@ 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::Wait(GetRootLayer()->GetCompositor());
+ ui::DrawWaiterForTest::WaitForCompositingEnded(
+ 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));
@@ -3364,7 +3370,8 @@ 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::Wait(GetRootLayer()->GetCompositor());
+ ui::DrawWaiterForTest::WaitForCompositingEnded(
+ 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));
@@ -3391,13 +3398,15 @@ 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::Wait(GetRootLayer()->GetCompositor());
+ ui::DrawWaiterForTest::WaitForCompositingEnded(
+ 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::Wait(GetRootLayer()->GetCompositor());
+ ui::DrawWaiterForTest::WaitForCompositingEnded(
+ 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));
@@ -3409,7 +3418,8 @@ TEST_F(ViewLayerTest, BoundsTreeWithRTL) {
gfx::Rect ltr_damage(16, 18, 1, 1);
test_view->SchedulePaintInRect(ltr_damage);
GetRootLayer()->GetCompositor()->ScheduleDraw();
- ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor());
+ ui::DrawWaiterForTest::WaitForCompositingEnded(
+ 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));
@@ -3433,18 +3443,21 @@ 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::Wait(GetRootLayer()->GetCompositor());
+ ui::DrawWaiterForTest::WaitForCompositingEnded(
+ 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::Wait(GetRootLayer()->GetCompositor());
+ ui::DrawWaiterForTest::WaitForCompositingEnded(
+ 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::Wait(GetRootLayer()->GetCompositor());
+ ui::DrawWaiterForTest::WaitForCompositingEnded(
+ GetRootLayer()->GetCompositor());
// Should only have picked up root_view and test_view.
EXPECT_EQ(2U, test_view->last_cull_set_.size());
@@ -3467,7 +3480,8 @@ 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::Wait(GetRootLayer()->GetCompositor());
+ ui::DrawWaiterForTest::WaitForCompositingEnded(
+ 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
@@ -3477,7 +3491,8 @@ TEST_F(ViewLayerTest, BoundsTreeLayerChangeMakesNewTree) {
// Schedule another full-view paint.
test_view->SchedulePaintInRect(test_view->bounds());
GetRootLayer()->GetCompositor()->ScheduleDraw();
- ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor());
+ ui::DrawWaiterForTest::WaitForCompositingEnded(
+ 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));
@@ -3488,7 +3503,8 @@ TEST_F(ViewLayerTest, BoundsTreeLayerChangeMakesNewTree) {
// Schedule another full-view paint.
test_view->SchedulePaintInRect(test_view->bounds());
GetRootLayer()->GetCompositor()->ScheduleDraw();
- ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor());
+ ui::DrawWaiterForTest::WaitForCompositingEnded(
+ 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()));
@@ -3512,7 +3528,8 @@ 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::Wait(GetRootLayer()->GetCompositor());
+ ui::DrawWaiterForTest::WaitForCompositingEnded(
+ GetRootLayer()->GetCompositor());
// Now remove v1 from the root view.
test_view->RemoveChildView(v1);
@@ -3520,7 +3537,8 @@ TEST_F(ViewLayerTest, BoundsTreeRemoveChildRemovesBounds) {
// Schedule another full-view paint.
test_view->SchedulePaintInRect(test_view->bounds());
GetRootLayer()->GetCompositor()->ScheduleDraw();
- ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor());
+ ui::DrawWaiterForTest::WaitForCompositingEnded(
+ 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));
@@ -3551,7 +3569,8 @@ 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::Wait(GetRootLayer()->GetCompositor());
+ ui::DrawWaiterForTest::WaitForCompositingEnded(
+ 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));
@@ -3574,7 +3593,8 @@ TEST_F(ViewLayerTest, BoundsTreeMoveViewMovesBounds) {
test_view->SchedulePaintInRect(test_view->bounds());
widget_view->SchedulePaintInRect(widget_view->bounds());
GetRootLayer()->GetCompositor()->ScheduleDraw();
- ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor());
+ ui::DrawWaiterForTest::WaitForCompositingEnded(
+ GetRootLayer()->GetCompositor());
// Only v1 should be present in the first cull set.
EXPECT_EQ(3U, test_view->last_cull_set_.size());