summaryrefslogtreecommitdiffstats
path: root/cc
diff options
context:
space:
mode:
authorskyostil <skyostil@chromium.org>2015-08-12 05:00:07 -0700
committerCommit bot <commit-bot@chromium.org>2015-08-12 12:00:51 +0000
commit51d1575b2df2fc681299c84e415cc078677b95e4 (patch)
tree881db86c384e81312dd6762aceb71eee6356231a /cc
parentc24635036139d941db318145b96fda64aeeda02b (diff)
downloadchromium_src-51d1575b2df2fc681299c84e415cc078677b95e4.zip
chromium_src-51d1575b2df2fc681299c84e415cc078677b95e4.tar.gz
chromium_src-51d1575b2df2fc681299c84e415cc078677b95e4.tar.bz2
cc: Make layer updating optional in BeginMainFrame
If no-one has requested a layer update, either by calling Proxy::SetNeedsUpdateLayers() or Proxy::SetNeedsCommit(), skip computing the layer update in BeginMainFrame. This reduces the static overhead of a BeginMainFrame/Commit operation when the layer tree doesn't change. This change improves efficiency, for example, when a page has a requestAnimationFrame callback which does not modify the DOM. BUG=490465 CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel Review URL: https://codereview.chromium.org/1255863004 Cr-Commit-Position: refs/heads/master@{#343004}
Diffstat (limited to 'cc')
-rw-r--r--cc/test/fake_layer_tree_host.h1
-rw-r--r--cc/test/layer_tree_test.cc6
-rw-r--r--cc/trees/layer_tree_host.cc12
-rw-r--r--cc/trees/layer_tree_host.h2
-rw-r--r--cc/trees/layer_tree_host_unittest_proxy.cc183
-rw-r--r--cc/trees/thread_proxy.cc106
-rw-r--r--cc/trees/thread_proxy.h29
7 files changed, 261 insertions, 78 deletions
diff --git a/cc/test/fake_layer_tree_host.h b/cc/test/fake_layer_tree_host.h
index 180e144..a50219c 100644
--- a/cc/test/fake_layer_tree_host.h
+++ b/cc/test/fake_layer_tree_host.h
@@ -30,6 +30,7 @@ class FakeLayerTreeHost : public LayerTreeHost {
~FakeLayerTreeHost() override;
void SetNeedsCommit() override;
+ void SetNeedsUpdateLayers() override {}
void SetNeedsFullTreeSync() override {}
using LayerTreeHost::SetRootLayer;
diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc
index 7823ef1..a866ac1 100644
--- a/cc/test/layer_tree_test.cc
+++ b/cc/test/layer_tree_test.cc
@@ -570,6 +570,12 @@ class LayerTreeHostForTesting : public LayerTreeHost {
LayerTreeHost::SetNeedsCommit();
}
+ void SetNeedsUpdateLayers() override {
+ if (!test_started_)
+ return;
+ LayerTreeHost::SetNeedsUpdateLayers();
+ }
+
void set_test_started(bool started) { test_started_ = started; }
private:
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc
index 4d72eb2..b3f7b1f 100644
--- a/cc/trees/layer_tree_host.cc
+++ b/cc/trees/layer_tree_host.cc
@@ -480,6 +480,11 @@ void LayerTreeHost::SetNeedsUpdateLayers() {
NotifySwapPromiseMonitorsOfSetNeedsCommit();
}
+void LayerTreeHost::SetPropertyTreesNeedRebuild() {
+ property_trees_.needs_rebuild = true;
+ SetNeedsUpdateLayers();
+}
+
void LayerTreeHost::SetNeedsCommit() {
proxy_->SetNeedsCommit();
NotifySwapPromiseMonitorsOfSetNeedsCommit();
@@ -520,6 +525,7 @@ void LayerTreeHost::SetNextCommitWaitsForActivation() {
void LayerTreeHost::SetNextCommitForcesRedraw() {
next_commit_forces_redraw_ = true;
+ proxy_->SetNeedsUpdateLayers();
}
void LayerTreeHost::SetAnimationEvents(
@@ -588,7 +594,7 @@ void LayerTreeHost::SetViewportSize(const gfx::Size& device_viewport_size) {
device_viewport_size_ = device_viewport_size;
- property_trees_.needs_rebuild = true;
+ SetPropertyTreesNeedRebuild();
SetNeedsCommit();
}
@@ -615,7 +621,7 @@ void LayerTreeHost::ApplyPageScaleDeltaFromImplSide(float page_scale_delta) {
if (page_scale_delta == 1.f)
return;
page_scale_factor_ *= page_scale_delta;
- property_trees_.needs_rebuild = true;
+ SetPropertyTreesNeedRebuild();
}
void LayerTreeHost::SetPageScaleFactorAndLimits(float page_scale_factor,
@@ -629,7 +635,7 @@ void LayerTreeHost::SetPageScaleFactorAndLimits(float page_scale_factor,
page_scale_factor_ = page_scale_factor;
min_page_scale_factor_ = min_page_scale_factor;
max_page_scale_factor_ = max_page_scale_factor;
- property_trees_.needs_rebuild = true;
+ SetPropertyTreesNeedRebuild();
SetNeedsCommit();
}
diff --git a/cc/trees/layer_tree_host.h b/cc/trees/layer_tree_host.h
index c04e8e7..a577f13 100644
--- a/cc/trees/layer_tree_host.h
+++ b/cc/trees/layer_tree_host.h
@@ -421,6 +421,8 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
void NotifySwapPromiseMonitorsOfSetNeedsCommit();
+ void SetPropertyTreesNeedRebuild();
+
bool inside_begin_main_frame_;
bool needs_full_tree_sync_;
bool needs_meta_info_recomputation_;
diff --git a/cc/trees/layer_tree_host_unittest_proxy.cc b/cc/trees/layer_tree_host_unittest_proxy.cc
index 66340e7..d4057cf 100644
--- a/cc/trees/layer_tree_host_unittest_proxy.cc
+++ b/cc/trees/layer_tree_host_unittest_proxy.cc
@@ -4,6 +4,8 @@
#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "cc/test/fake_content_layer_client.h"
+#include "cc/test/fake_picture_layer.h"
#include "cc/test/layer_tree_test.h"
#include "cc/trees/thread_proxy.h"
@@ -71,9 +73,16 @@ PROXY_TEST_SCHEDULED_ACTION(ProxyTestScheduledActionsBasic);
class ThreadProxyTest : public ProxyTest {
protected:
- ThreadProxyTest() {}
+ ThreadProxyTest()
+ : update_check_layer_(
+ FakePictureLayer::Create(layer_settings(), &client_)) {}
~ThreadProxyTest() override {}
+ void SetupTree() override {
+ layer_tree_host()->SetRootLayer(update_check_layer_);
+ ProxyTest::SetupTree();
+ }
+
const ThreadProxy::MainThreadOnly& ThreadProxyMainOnly() const {
DCHECK(proxy());
DCHECK(proxy()->HasImplThread());
@@ -86,6 +95,10 @@ class ThreadProxyTest : public ProxyTest {
return static_cast<const ThreadProxy*>(proxy())->impl();
}
+ protected:
+ FakeContentLayerClient client_;
+ scoped_refptr<FakePictureLayer> update_check_layer_;
+
private:
DISALLOW_COPY_AND_ASSIGN(ThreadProxyTest);
};
@@ -96,19 +109,26 @@ class ThreadProxyTestSetNeedsCommit : public ThreadProxyTest {
~ThreadProxyTestSetNeedsCommit() override {}
void BeginTest() override {
- EXPECT_FALSE(ThreadProxyMainOnly().commit_requested);
- EXPECT_FALSE(ThreadProxyMainOnly().commit_request_sent_to_impl_thread);
+ EXPECT_EQ(ThreadProxy::NO_PIPELINE_STAGE,
+ ThreadProxyMainOnly().max_requested_pipeline_stage);
proxy()->SetNeedsCommit();
- EXPECT_TRUE(ThreadProxyMainOnly().commit_requested);
- EXPECT_TRUE(ThreadProxyMainOnly().commit_request_sent_to_impl_thread);
+ EXPECT_EQ(ThreadProxy::COMMIT_PIPELINE_STAGE,
+ ThreadProxyMainOnly().max_requested_pipeline_stage);
}
void DidBeginMainFrame() override {
- EXPECT_FALSE(ThreadProxyMainOnly().commit_requested);
- EXPECT_FALSE(ThreadProxyMainOnly().commit_request_sent_to_impl_thread);
+ EXPECT_EQ(ThreadProxy::NO_PIPELINE_STAGE,
+ ThreadProxyMainOnly().max_requested_pipeline_stage);
+ EXPECT_EQ(ThreadProxy::NO_PIPELINE_STAGE,
+ ThreadProxyMainOnly().current_pipeline_stage);
+ }
+ void DidCommit() override {
+ EXPECT_EQ(1, update_check_layer_->update_count());
+ EXPECT_EQ(ThreadProxy::NO_PIPELINE_STAGE,
+ ThreadProxyMainOnly().current_pipeline_stage);
EndTest();
}
@@ -118,4 +138,153 @@ class ThreadProxyTestSetNeedsCommit : public ThreadProxyTest {
THREAD_PROXY_TEST_F(ThreadProxyTestSetNeedsCommit);
+class ThreadProxyTestSetNeedsAnimate : public ThreadProxyTest {
+ protected:
+ ThreadProxyTestSetNeedsAnimate() {}
+ ~ThreadProxyTestSetNeedsAnimate() override {}
+
+ void BeginTest() override {
+ EXPECT_EQ(ThreadProxy::NO_PIPELINE_STAGE,
+ ThreadProxyMainOnly().max_requested_pipeline_stage);
+
+ proxy()->SetNeedsAnimate();
+
+ EXPECT_EQ(ThreadProxy::ANIMATE_PIPELINE_STAGE,
+ ThreadProxyMainOnly().max_requested_pipeline_stage);
+ }
+
+ void DidBeginMainFrame() override {
+ EXPECT_EQ(ThreadProxy::NO_PIPELINE_STAGE,
+ ThreadProxyMainOnly().max_requested_pipeline_stage);
+ EXPECT_EQ(ThreadProxy::NO_PIPELINE_STAGE,
+ ThreadProxyMainOnly().current_pipeline_stage);
+ }
+
+ void DidCommit() override {
+ EXPECT_EQ(0, update_check_layer_->update_count());
+ EndTest();
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ThreadProxyTestSetNeedsAnimate);
+};
+
+THREAD_PROXY_TEST_F(ThreadProxyTestSetNeedsAnimate);
+
+class ThreadProxyTestSetNeedsUpdateLayers : public ThreadProxyTest {
+ protected:
+ ThreadProxyTestSetNeedsUpdateLayers() {}
+ ~ThreadProxyTestSetNeedsUpdateLayers() override {}
+
+ void BeginTest() override {
+ EXPECT_EQ(ThreadProxy::NO_PIPELINE_STAGE,
+ ThreadProxyMainOnly().max_requested_pipeline_stage);
+
+ proxy()->SetNeedsUpdateLayers();
+
+ EXPECT_EQ(ThreadProxy::UPDATE_LAYERS_PIPELINE_STAGE,
+ ThreadProxyMainOnly().max_requested_pipeline_stage);
+ }
+
+ void DidBeginMainFrame() override {
+ EXPECT_EQ(ThreadProxy::NO_PIPELINE_STAGE,
+ ThreadProxyMainOnly().max_requested_pipeline_stage);
+ EXPECT_EQ(ThreadProxy::NO_PIPELINE_STAGE,
+ ThreadProxyMainOnly().current_pipeline_stage);
+ }
+
+ void DidCommit() override {
+ EXPECT_EQ(1, update_check_layer_->update_count());
+ EndTest();
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ThreadProxyTestSetNeedsUpdateLayers);
+};
+
+THREAD_PROXY_TEST_F(ThreadProxyTestSetNeedsUpdateLayers);
+
+class ThreadProxyTestSetNeedsUpdateLayersWhileAnimating
+ : public ThreadProxyTest {
+ protected:
+ ThreadProxyTestSetNeedsUpdateLayersWhileAnimating() {}
+ ~ThreadProxyTestSetNeedsUpdateLayersWhileAnimating() override {}
+
+ void BeginTest() override { proxy()->SetNeedsAnimate(); }
+
+ void WillBeginMainFrame() override {
+ EXPECT_EQ(ThreadProxy::NO_PIPELINE_STAGE,
+ ThreadProxyMainOnly().max_requested_pipeline_stage);
+ EXPECT_EQ(ThreadProxy::ANIMATE_PIPELINE_STAGE,
+ ThreadProxyMainOnly().current_pipeline_stage);
+ EXPECT_EQ(ThreadProxy::ANIMATE_PIPELINE_STAGE,
+ ThreadProxyMainOnly().final_pipeline_stage);
+
+ proxy()->SetNeedsUpdateLayers();
+
+ EXPECT_EQ(ThreadProxy::NO_PIPELINE_STAGE,
+ ThreadProxyMainOnly().max_requested_pipeline_stage);
+ EXPECT_EQ(ThreadProxy::UPDATE_LAYERS_PIPELINE_STAGE,
+ ThreadProxyMainOnly().final_pipeline_stage);
+ }
+
+ void DidBeginMainFrame() override {
+ EXPECT_EQ(ThreadProxy::NO_PIPELINE_STAGE,
+ ThreadProxyMainOnly().max_requested_pipeline_stage);
+ EXPECT_EQ(ThreadProxy::NO_PIPELINE_STAGE,
+ ThreadProxyMainOnly().current_pipeline_stage);
+ }
+
+ void DidCommit() override {
+ EXPECT_EQ(1, update_check_layer_->update_count());
+ EndTest();
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ThreadProxyTestSetNeedsUpdateLayersWhileAnimating);
+};
+
+THREAD_PROXY_TEST_F(ThreadProxyTestSetNeedsUpdateLayersWhileAnimating);
+
+class ThreadProxyTestSetNeedsCommitWhileAnimating : public ThreadProxyTest {
+ protected:
+ ThreadProxyTestSetNeedsCommitWhileAnimating() {}
+ ~ThreadProxyTestSetNeedsCommitWhileAnimating() override {}
+
+ void BeginTest() override { proxy()->SetNeedsAnimate(); }
+
+ void WillBeginMainFrame() override {
+ EXPECT_EQ(ThreadProxy::NO_PIPELINE_STAGE,
+ ThreadProxyMainOnly().max_requested_pipeline_stage);
+ EXPECT_EQ(ThreadProxy::ANIMATE_PIPELINE_STAGE,
+ ThreadProxyMainOnly().current_pipeline_stage);
+ EXPECT_EQ(ThreadProxy::ANIMATE_PIPELINE_STAGE,
+ ThreadProxyMainOnly().final_pipeline_stage);
+
+ proxy()->SetNeedsCommit();
+
+ EXPECT_EQ(ThreadProxy::NO_PIPELINE_STAGE,
+ ThreadProxyMainOnly().max_requested_pipeline_stage);
+ EXPECT_EQ(ThreadProxy::COMMIT_PIPELINE_STAGE,
+ ThreadProxyMainOnly().final_pipeline_stage);
+ }
+
+ void DidBeginMainFrame() override {
+ EXPECT_EQ(ThreadProxy::NO_PIPELINE_STAGE,
+ ThreadProxyMainOnly().max_requested_pipeline_stage);
+ EXPECT_EQ(ThreadProxy::NO_PIPELINE_STAGE,
+ ThreadProxyMainOnly().current_pipeline_stage);
+ }
+
+ void DidCommit() override {
+ EXPECT_EQ(1, update_check_layer_->update_count());
+ EndTest();
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ThreadProxyTestSetNeedsCommitWhileAnimating);
+};
+
+THREAD_PROXY_TEST_F(ThreadProxyTestSetNeedsCommitWhileAnimating);
+
} // namespace cc
diff --git a/cc/trees/thread_proxy.cc b/cc/trees/thread_proxy.cc
index a528e3e..ba1f946 100644
--- a/cc/trees/thread_proxy.cc
+++ b/cc/trees/thread_proxy.cc
@@ -76,15 +76,13 @@ ThreadProxy::ThreadProxy(
ThreadProxy::MainThreadOnly::MainThreadOnly(ThreadProxy* proxy,
int layer_tree_host_id)
: layer_tree_host_id(layer_tree_host_id),
- animate_requested(false),
- commit_requested(false),
- commit_request_sent_to_impl_thread(false),
+ max_requested_pipeline_stage(NO_PIPELINE_STAGE),
+ current_pipeline_stage(NO_PIPELINE_STAGE),
+ final_pipeline_stage(NO_PIPELINE_STAGE),
started(false),
prepare_tiles_pending(false),
- can_cancel_commit(true),
defer_commits(false),
- weak_factory(proxy) {
-}
+ weak_factory(proxy) {}
ThreadProxy::MainThreadOnly::~MainThreadOnly() {}
@@ -238,11 +236,16 @@ void ThreadProxy::SetRendererCapabilitiesMainThreadCopy(
main().renderer_capabilities_main_thread_copy = capabilities;
}
-void ThreadProxy::SendCommitRequestToImplThreadIfNeeded() {
+void ThreadProxy::SendCommitRequestToImplThreadIfNeeded(
+ CommitPipelineStage required_stage) {
DCHECK(IsMainThread());
- if (main().commit_request_sent_to_impl_thread)
+ DCHECK_NE(NO_PIPELINE_STAGE, required_stage);
+ bool already_posted =
+ main().max_requested_pipeline_stage != NO_PIPELINE_STAGE;
+ main().max_requested_pipeline_stage =
+ std::max(main().max_requested_pipeline_stage, required_stage);
+ if (already_posted)
return;
- main().commit_request_sent_to_impl_thread = true;
Proxy::ImplThreadTaskRunner()->PostTask(
FROM_HERE,
base::Bind(&ThreadProxy::SetNeedsCommitOnImplThread,
@@ -262,35 +265,34 @@ const RendererCapabilities& ThreadProxy::GetRendererCapabilities() const {
void ThreadProxy::SetNeedsAnimate() {
DCHECK(IsMainThread());
- if (main().animate_requested)
- return;
-
TRACE_EVENT0("cc", "ThreadProxy::SetNeedsAnimate");
- main().animate_requested = true;
- SendCommitRequestToImplThreadIfNeeded();
+ SendCommitRequestToImplThreadIfNeeded(ANIMATE_PIPELINE_STAGE);
}
void ThreadProxy::SetNeedsUpdateLayers() {
DCHECK(IsMainThread());
-
- if (main().commit_request_sent_to_impl_thread)
- return;
TRACE_EVENT0("cc", "ThreadProxy::SetNeedsUpdateLayers");
-
- SendCommitRequestToImplThreadIfNeeded();
+ // If we are currently animating, make sure we also update the layers.
+ if (main().current_pipeline_stage == ANIMATE_PIPELINE_STAGE) {
+ main().final_pipeline_stage =
+ std::max(main().final_pipeline_stage, UPDATE_LAYERS_PIPELINE_STAGE);
+ return;
+ }
+ SendCommitRequestToImplThreadIfNeeded(UPDATE_LAYERS_PIPELINE_STAGE);
}
void ThreadProxy::SetNeedsCommit() {
DCHECK(IsMainThread());
- // Unconditionally set here to handle SetNeedsCommit calls during a commit.
- main().can_cancel_commit = false;
-
- if (main().commit_requested)
+ // If we are currently animating, make sure we don't skip the commit. Note
+ // that requesting a commit during the layer update stage means we need to
+ // schedule another full commit.
+ if (main().current_pipeline_stage == ANIMATE_PIPELINE_STAGE) {
+ main().final_pipeline_stage =
+ std::max(main().final_pipeline_stage, COMMIT_PIPELINE_STAGE);
return;
+ }
TRACE_EVENT0("cc", "ThreadProxy::SetNeedsCommit");
- main().commit_requested = true;
-
- SendCommitRequestToImplThreadIfNeeded();
+ SendCommitRequestToImplThreadIfNeeded(COMMIT_PIPELINE_STAGE);
}
void ThreadProxy::UpdateRendererCapabilitiesOnImplThread() {
@@ -441,12 +443,15 @@ void ThreadProxy::SetDeferCommitsOnImplThread(bool defer_commits) const {
bool ThreadProxy::CommitRequested() const {
DCHECK(IsMainThread());
- return main().commit_requested;
+ // TODO(skyostil): Split this into something like CommitRequested() and
+ // CommitInProgress().
+ return main().current_pipeline_stage != NO_PIPELINE_STAGE ||
+ main().max_requested_pipeline_stage >= COMMIT_PIPELINE_STAGE;
}
bool ThreadProxy::BeginMainFrameRequested() const {
DCHECK(IsMainThread());
- return main().commit_request_sent_to_impl_thread;
+ return main().max_requested_pipeline_stage != NO_PIPELINE_STAGE;
}
void ThreadProxy::SetNeedsRedrawOnImplThread() {
@@ -680,6 +685,7 @@ void ThreadProxy::BeginMainFrame(
begin_main_frame_state->begin_frame_id);
TRACE_EVENT_SYNTHETIC_DELAY_BEGIN("cc.BeginMainFrame");
DCHECK(IsMainThread());
+ DCHECK_EQ(NO_PIPELINE_STAGE, main().current_pipeline_stage);
if (main().defer_commits) {
TRACE_EVENT_INSTANT0("cc", "EarlyOut_DeferCommit",
@@ -696,9 +702,8 @@ void ThreadProxy::BeginMainFrame(
// remaining swap promises.
ScopedAbortRemainingSwapPromises swap_promise_checker(layer_tree_host());
- main().commit_requested = false;
- main().commit_request_sent_to_impl_thread = false;
- main().animate_requested = false;
+ main().final_pipeline_stage = main().max_requested_pipeline_stage;
+ main().max_requested_pipeline_stage = NO_PIPELINE_STAGE;
if (!layer_tree_host()->visible()) {
TRACE_EVENT_INSTANT0("cc", "EarlyOut_NotVisible", TRACE_EVENT_SCOPE_THREAD);
@@ -720,16 +725,7 @@ void ThreadProxy::BeginMainFrame(
return;
}
- // Do not notify the impl thread of commit requests that occur during
- // the apply/animate/layout part of the BeginMainFrameAndCommit process since
- // those commit requests will get painted immediately. Once we have done
- // the paint, main().commit_requested will be set to false to allow new commit
- // requests to be scheduled.
- // On the other hand, the animate_requested flag should remain cleared
- // here so that any animation requests generated by the apply or animate
- // callbacks will trigger another frame.
- main().commit_requested = true;
- main().commit_request_sent_to_impl_thread = true;
+ main().current_pipeline_stage = ANIMATE_PIPELINE_STAGE;
layer_tree_host()->ApplyScrollAndScale(
begin_main_frame_state->scroll_info.get());
@@ -748,32 +744,20 @@ void ThreadProxy::BeginMainFrame(
layer_tree_host()->Layout();
TRACE_EVENT_SYNTHETIC_DELAY_END("cc.BeginMainFrame");
- // Clear the commit flag after updating animations and layout here --- objects
- // that only layout when painted will trigger another SetNeedsCommit inside
- // UpdateLayers.
- main().commit_requested = false;
- main().commit_request_sent_to_impl_thread = false;
bool can_cancel_this_commit =
- main().can_cancel_commit && !begin_main_frame_state->evicted_ui_resources;
- main().can_cancel_commit = true;
+ main().final_pipeline_stage < COMMIT_PIPELINE_STAGE &&
+ !begin_main_frame_state->evicted_ui_resources;
- bool updated = layer_tree_host()->UpdateLayers();
+ main().current_pipeline_stage = UPDATE_LAYERS_PIPELINE_STAGE;
+ bool should_update_layers =
+ main().final_pipeline_stage >= UPDATE_LAYERS_PIPELINE_STAGE;
+ bool updated = should_update_layers && layer_tree_host()->UpdateLayers();
layer_tree_host()->WillCommit();
devtools_instrumentation::ScopedCommitTrace commit_task(
layer_tree_host()->id());
- // Before calling animate, we set main().animate_requested to false. If it is
- // true now, it means SetNeedAnimate was called again, but during a state when
- // main().commit_request_sent_to_impl_thread = true. We need to force that
- // call to happen again now so that the commit request is sent to the impl
- // thread.
- if (main().animate_requested) {
- // Forces SetNeedsAnimate to consider posting a commit task.
- main().animate_requested = false;
- SetNeedsAnimate();
- }
-
+ main().current_pipeline_stage = COMMIT_PIPELINE_STAGE;
if (!updated && can_cancel_this_commit) {
TRACE_EVENT_INSTANT0("cc", "EarlyOut_NoUpdates", TRACE_EVENT_SCOPE_THREAD);
Proxy::ImplThreadTaskRunner()->PostTask(
@@ -784,6 +768,7 @@ void ThreadProxy::BeginMainFrame(
// Although the commit is internally aborted, this is because it has been
// detected to be a no-op. From the perspective of an embedder, this commit
// went through, and input should no longer be throttled, etc.
+ main().current_pipeline_stage = NO_PIPELINE_STAGE;
layer_tree_host()->CommitComplete();
layer_tree_host()->DidBeginMainFrame();
layer_tree_host()->BreakSwapPromises(SwapPromise::COMMIT_NO_UPDATE);
@@ -812,6 +797,7 @@ void ThreadProxy::BeginMainFrame(
completion.Wait();
}
+ main().current_pipeline_stage = NO_PIPELINE_STAGE;
layer_tree_host()->CommitComplete();
layer_tree_host()->DidBeginMainFrame();
}
diff --git a/cc/trees/thread_proxy.h b/cc/trees/thread_proxy.h
index ca76e42..a2e7bec 100644
--- a/cc/trees/thread_proxy.h
+++ b/cc/trees/thread_proxy.h
@@ -54,22 +54,34 @@ class CC_EXPORT ThreadProxy : public Proxy,
bool evicted_ui_resources;
};
+ // Commits between the main and impl threads are processed through a pipeline
+ // with the following stages. For efficiency we can early out at any stage if
+ // we decide that no further processing is necessary.
+ enum CommitPipelineStage {
+ NO_PIPELINE_STAGE,
+ ANIMATE_PIPELINE_STAGE,
+ UPDATE_LAYERS_PIPELINE_STAGE,
+ COMMIT_PIPELINE_STAGE,
+ };
+
struct MainThreadOnly {
MainThreadOnly(ThreadProxy* proxy, int layer_tree_host_id);
~MainThreadOnly();
const int layer_tree_host_id;
- // Set only when SetNeedsAnimate is called.
- bool animate_requested;
- // Set only when SetNeedsCommit is called.
- bool commit_requested;
- // Set by SetNeedsAnimate, SetNeedsUpdateLayers, and SetNeedsCommit.
- bool commit_request_sent_to_impl_thread;
+ // The furthest pipeline stage which has been requested for the next
+ // commit.
+ CommitPipelineStage max_requested_pipeline_stage;
+ // The commit pipeline stage that is currently being processed.
+ CommitPipelineStage current_pipeline_stage;
+ // The commit pipeline stage at which processing for the current commit
+ // will stop. Only valid while we are executing the pipeline (i.e.,
+ // |current_pipeline_stage| is set to a pipeline stage).
+ CommitPipelineStage final_pipeline_stage;
bool started;
bool prepare_tiles_pending;
- bool can_cancel_commit;
bool defer_commits;
RendererCapabilities renderer_capabilities_main_thread_copy;
@@ -243,7 +255,8 @@ class CC_EXPORT ThreadProxy : public Proxy,
void RequestNewOutputSurface();
void DidInitializeOutputSurface(bool success,
const RendererCapabilities& capabilities);
- void SendCommitRequestToImplThreadIfNeeded();
+ void SendCommitRequestToImplThreadIfNeeded(
+ CommitPipelineStage required_stage);
void DidCompletePageScaleAnimation();
// Called on impl thread.