summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordanakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-13 14:01:29 +0000
committerdanakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-13 14:01:29 +0000
commit2a61ad5338b93b7eb55e9b76a99531165b24b08b (patch)
treefc889ce0c9875987efd07ceeb958cb4bb00058a4
parentd242cb3f2ddf1469d4eb71fc190c9ce122e16d2b (diff)
downloadchromium_src-2a61ad5338b93b7eb55e9b76a99531165b24b08b.zip
chromium_src-2a61ad5338b93b7eb55e9b76a99531165b24b08b.tar.gz
chromium_src-2a61ad5338b93b7eb55e9b76a99531165b24b08b.tar.bz2
Run all LayerTreeHost tests with impl-side painting.
This will be always on in the future. All tests should pass with it enabled. If a pending tree is activated during draw, it requests another redraw. If the context is also lost during the activation draw, we end up trying to draw the active tree with its lost resources, instead of doing a commit to get new resources. This is fixed and covered by SchedulerStateMachineTest.DontDrawBeforeCommitAfterLostOutputSurface If you commit and pending tree with animations, but are unable to draw, we would activate the pending tree via an animation tick, but never unblock the main thread if it was waiting on the activation to finish commit. This is covered by the animation unit tests. Similarly, if you commited a tree without animations, it would be activated by the thread proxy without drawing, but the main thread would remain blocked. This was uncovered and is covered by layer tree host tests. When an active tree has layers in it, and the root layer is removed, the impl side would crash trying to use the non-existent pending tree's root layer. This is fixed in LayerTreeImpl::ClearRenderSurfaces() and PushPersistedState(). BUG=239329 Review URL: https://chromiumcodereview.appspot.com/15004013 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@199721 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--cc/layers/delegated_renderer_layer.cc8
-rw-r--r--cc/layers/delegated_renderer_layer.h2
-rw-r--r--cc/layers/delegated_renderer_layer_impl.cc43
-rw-r--r--cc/layers/delegated_renderer_layer_impl.h4
-rw-r--r--cc/layers/scrollbar_layer_unittest.cc8
-rw-r--r--cc/output/delegating_renderer.cc1
-rw-r--r--cc/quads/render_pass.cc2
-rw-r--r--cc/scheduler/scheduler_state_machine.cc6
-rw-r--r--cc/scheduler/scheduler_state_machine_unittest.cc22
-rw-r--r--cc/test/fake_content_layer_impl.cc6
-rw-r--r--cc/test/fake_content_layer_impl.h3
-rw-r--r--cc/test/fake_layer_tree_host_impl_client.h1
-rw-r--r--cc/test/layer_tree_pixel_test.cc4
-rw-r--r--cc/test/layer_tree_test.cc10
-rw-r--r--cc/test/layer_tree_test.h30
-rw-r--r--cc/trees/layer_tree_host_impl.cc2
-rw-r--r--cc/trees/layer_tree_host_impl.h1
-rw-r--r--cc/trees/layer_tree_host_impl_unittest.cc1
-rw-r--r--cc/trees/layer_tree_host_perftest.cc19
-rw-r--r--cc/trees/layer_tree_host_unittest.cc114
-rw-r--r--cc/trees/layer_tree_host_unittest_animation.cc13
-rw-r--r--cc/trees/layer_tree_host_unittest_context.cc177
-rw-r--r--cc/trees/layer_tree_host_unittest_damage.cc13
-rw-r--r--cc/trees/layer_tree_host_unittest_scroll.cc53
-rw-r--r--cc/trees/layer_tree_impl.cc12
-rw-r--r--cc/trees/single_thread_proxy.h1
-rw-r--r--cc/trees/thread_proxy.cc26
-rw-r--r--cc/trees/thread_proxy.h1
28 files changed, 437 insertions, 146 deletions
diff --git a/cc/layers/delegated_renderer_layer.cc b/cc/layers/delegated_renderer_layer.cc
index 81a9bdf..216d00d 100644
--- a/cc/layers/delegated_renderer_layer.cc
+++ b/cc/layers/delegated_renderer_layer.cc
@@ -107,4 +107,12 @@ void DelegatedRendererLayer::TakeUnusedResourcesForChildCompositor(
array->swap(unused_resources_for_child_compositor_);
}
+bool DelegatedRendererLayer::BlocksPendingCommit() const {
+ // The active frame needs to be replaced and resources returned before the
+ // commit is called complete. This is true even whenever there may be
+ // resources to return, regardless of if the layer will draw in its new
+ // state.
+ return true;
+}
+
} // namespace cc
diff --git a/cc/layers/delegated_renderer_layer.h b/cc/layers/delegated_renderer_layer.h
index 5e833b6..3f5280e 100644
--- a/cc/layers/delegated_renderer_layer.h
+++ b/cc/layers/delegated_renderer_layer.h
@@ -36,6 +36,8 @@ class CC_EXPORT DelegatedRendererLayer : public Layer {
// compositor to the given array, so they can be given back to the child.
void TakeUnusedResourcesForChildCompositor(TransferableResourceArray* array);
+ virtual bool BlocksPendingCommit() const OVERRIDE;
+
protected:
explicit DelegatedRendererLayer(DelegatedRendererLayerClient* client);
virtual ~DelegatedRendererLayer();
diff --git a/cc/layers/delegated_renderer_layer_impl.cc b/cc/layers/delegated_renderer_layer_impl.cc
index 6c1afac..ef5052d5 100644
--- a/cc/layers/delegated_renderer_layer_impl.cc
+++ b/cc/layers/delegated_renderer_layer_impl.cc
@@ -23,7 +23,9 @@ namespace cc {
DelegatedRendererLayerImpl::DelegatedRendererLayerImpl(
LayerTreeImpl* tree_impl, int id)
: LayerImpl(tree_impl, id),
- child_id_(0) {
+ have_render_passes_to_push_(false),
+ child_id_(0),
+ own_child_id_(false) {
}
DelegatedRendererLayerImpl::~DelegatedRendererLayerImpl() {
@@ -61,6 +63,33 @@ static ResourceProvider::ResourceId ResourceRemapHelper(
return remapped_id;
}
+void DelegatedRendererLayerImpl::PushPropertiesTo(LayerImpl* layer) {
+ LayerImpl::PushPropertiesTo(layer);
+
+ DelegatedRendererLayerImpl* delegated_layer =
+ static_cast<DelegatedRendererLayerImpl*>(layer);
+
+ // If we have a new child_id to give to the active layer, it should
+ // have already deleted its old child_id.
+ DCHECK(delegated_layer->child_id_ == 0 ||
+ delegated_layer->child_id_ == child_id_);
+ delegated_layer->child_id_ = child_id_;
+ delegated_layer->own_child_id_ = true;
+ own_child_id_ = false;
+
+ delegated_layer->SetDisplaySize(display_size_);
+ if (have_render_passes_to_push_) {
+ // This passes ownership of the render passes to the active tree.
+ delegated_layer->SetRenderPasses(&render_passes_in_draw_order_);
+ DCHECK(render_passes_in_draw_order_.empty());
+ have_render_passes_to_push_ = false;
+ }
+
+ // This is just a copy for testing since we keep the data on the pending layer
+ // for returning resources to the child for now.
+ delegated_layer->resources_ = resources_;
+}
+
void DelegatedRendererLayerImpl::SetFrameData(
scoped_ptr<DelegatedFrameData> frame_data,
gfx::RectF damage_in_frame,
@@ -110,6 +139,7 @@ void DelegatedRendererLayerImpl::SetFrameData(
// passes from the frame_data.
SetRenderPasses(&frame_data->render_pass_list);
resources_.swap(used_resources);
+ have_render_passes_to_push_ = true;
}
}
@@ -154,6 +184,9 @@ void DelegatedRendererLayerImpl::SetRenderPasses(
if (!render_passes_in_draw_order_.empty())
render_passes_in_draw_order_.back()->damage_rect.Union(old_root_damage);
+
+ // Give back an empty array instead of nulls.
+ render_passes_in_draw_order->clear();
}
void DelegatedRendererLayerImpl::ClearRenderPasses() {
@@ -421,14 +454,18 @@ void DelegatedRendererLayerImpl::CreateChildIdIfNeeded() {
ResourceProvider* resource_provider = layer_tree_impl()->resource_provider();
child_id_ = resource_provider->CreateChild();
+ own_child_id_ = true;
}
void DelegatedRendererLayerImpl::ClearChildId() {
if (!child_id_)
return;
- ResourceProvider* resource_provider = layer_tree_impl()->resource_provider();
- resource_provider->DestroyChild(child_id_);
+ if (own_child_id_) {
+ ResourceProvider* provider = layer_tree_impl()->resource_provider();
+ provider->DestroyChild(child_id_);
+ }
+
child_id_ = 0;
}
diff --git a/cc/layers/delegated_renderer_layer_impl.h b/cc/layers/delegated_renderer_layer_impl.h
index ec86200..c70dd14 100644
--- a/cc/layers/delegated_renderer_layer_impl.h
+++ b/cc/layers/delegated_renderer_layer_impl.h
@@ -5,6 +5,7 @@
#ifndef CC_LAYERS_DELEGATED_RENDERER_LAYER_IMPL_H_
#define CC_LAYERS_DELEGATED_RENDERER_LAYER_IMPL_H_
+#include "base/hash_tables.h"
#include "base/memory/scoped_ptr.h"
#include "cc/base/cc_export.h"
#include "cc/base/scoped_ptr_vector.h"
@@ -33,6 +34,7 @@ class CC_EXPORT DelegatedRendererLayerImpl : public LayerImpl {
virtual void DidLoseOutputSurface() OVERRIDE;
virtual void AppendQuads(QuadSink* quad_sink,
AppendQuadsData* append_quads_data) OVERRIDE;
+ virtual void PushPropertiesTo(LayerImpl* layer) OVERRIDE;
void AppendContributingRenderPasses(RenderPassSink* render_pass_sink);
@@ -81,12 +83,14 @@ class CC_EXPORT DelegatedRendererLayerImpl : public LayerImpl {
// LayerImpl overrides.
virtual const char* LayerTypeAsString() const OVERRIDE;
+ bool have_render_passes_to_push_;
ScopedPtrVector<RenderPass> render_passes_in_draw_order_;
base::hash_map<RenderPass::Id, int> render_passes_index_by_id_;
ResourceProvider::ResourceIdSet resources_;
gfx::Size display_size_;
int child_id_;
+ bool own_child_id_;
DISALLOW_COPY_AND_ASSIGN(DelegatedRendererLayerImpl);
};
diff --git a/cc/layers/scrollbar_layer_unittest.cc b/cc/layers/scrollbar_layer_unittest.cc
index 9cc0165..a20c1f5 100644
--- a/cc/layers/scrollbar_layer_unittest.cc
+++ b/cc/layers/scrollbar_layer_unittest.cc
@@ -305,9 +305,9 @@ class ScrollbarLayerTestMaxTextureSize : public LayerTreeTest {
PostSetNeedsCommitToMainThread();
}
- virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
+ virtual void DidCommitAndDrawFrame() OVERRIDE {
const int kMaxTextureSize =
- impl->GetRendererCapabilities().max_texture_size;
+ layer_tree_host()->GetRendererCapabilities().max_texture_size;
// Check first that we're actually testing something.
EXPECT_GT(scrollbar_layer_->bounds().width(), kMaxTextureSize);
@@ -334,7 +334,7 @@ TEST_F(ScrollbarLayerTestMaxTextureSize, DirectRenderer) {
int max_size = 0;
context->getIntegerv(GL_MAX_TEXTURE_SIZE, &max_size);
SetScrollbarBounds(gfx::Size(max_size + 100, max_size + 100));
- RunTest(true, false);
+ RunTest(true, false, true);
}
TEST_F(ScrollbarLayerTestMaxTextureSize, DelegatingRenderer) {
@@ -343,7 +343,7 @@ TEST_F(ScrollbarLayerTestMaxTextureSize, DelegatingRenderer) {
int max_size = 0;
context->getIntegerv(GL_MAX_TEXTURE_SIZE, &max_size);
SetScrollbarBounds(gfx::Size(max_size + 100, max_size + 100));
- RunTest(true, true);
+ RunTest(true, true, true);
}
class MockLayerTreeHost : public LayerTreeHost {
diff --git a/cc/output/delegating_renderer.cc b/cc/output/delegating_renderer.cc
index 2565add..e3a784e 100644
--- a/cc/output/delegating_renderer.cc
+++ b/cc/output/delegating_renderer.cc
@@ -58,6 +58,7 @@ bool DelegatingRenderer::Initialize() {
capabilities_.max_texture_size = resource_provider_->max_texture_size();
capabilities_.best_texture_format = resource_provider_->best_texture_format();
capabilities_.allow_partial_texture_updates = false;
+ capabilities_.using_offscreen_context3d = false;
WebGraphicsContext3D* context3d = resource_provider_->GraphicsContext3D();
diff --git a/cc/quads/render_pass.cc b/cc/quads/render_pass.cc
index 48990cd..56a90c8 100644
--- a/cc/quads/render_pass.cc
+++ b/cc/quads/render_pass.cc
@@ -21,8 +21,6 @@ RenderPass::RenderPass()
RenderPass::~RenderPass() {}
scoped_ptr<RenderPass> RenderPass::Copy(Id new_id) const {
- DCHECK(new_id != id);
-
scoped_ptr<RenderPass> copy_pass(Create());
copy_pass->SetAll(new_id,
output_rect,
diff --git a/cc/scheduler/scheduler_state_machine.cc b/cc/scheduler/scheduler_state_machine.cc
index df935aa..63ba414 100644
--- a/cc/scheduler/scheduler_state_machine.cc
+++ b/cc/scheduler/scheduler_state_machine.cc
@@ -429,7 +429,11 @@ void SchedulerStateMachine::DidCreateAndInitializeOutputSurface() {
if (did_create_and_initialize_first_output_surface_) {
// TODO(boliu): See if we can remove this when impl-side painting is always
// on. Does anything on the main thread need to update after recreate?
- SetNeedsCommit();
+ needs_commit_ = true;
+ // If anything has requested a redraw, we don't want to actually draw
+ // when the output surface is restored until things have a chance to
+ // sort themselves out with a commit.
+ needs_redraw_ = false;
}
did_create_and_initialize_first_output_surface_ = true;
}
diff --git a/cc/scheduler/scheduler_state_machine_unittest.cc b/cc/scheduler/scheduler_state_machine_unittest.cc
index c4cdd84..117c778 100644
--- a/cc/scheduler/scheduler_state_machine_unittest.cc
+++ b/cc/scheduler/scheduler_state_machine_unittest.cc
@@ -938,6 +938,28 @@ TEST(SchedulerStateMachineTest, TestFinishAllRenderingWhileContextLost) {
state.DidLeaveVSync();
}
+TEST(SchedulerStateMachineTest, DontDrawBeforeCommitAfterLostOutputSurface) {
+ SchedulerSettings default_scheduler_settings;
+ StateMachine state(default_scheduler_settings);
+ state.SetCanStart();
+ state.UpdateState(state.NextAction());
+ state.DidCreateAndInitializeOutputSurface();
+ state.SetVisible(true);
+ state.SetCanDraw(true);
+
+ state.SetNeedsRedraw(true);
+
+ // Cause a lost output surface, and restore it.
+ state.DidLoseOutputSurface();
+ EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
+ state.NextAction());
+ state.UpdateState(state.NextAction());
+ state.DidCreateAndInitializeOutputSurface();
+
+ EXPECT_FALSE(state.RedrawPending());
+ EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_FRAME, state.NextAction());
+}
+
TEST(SchedulerStateMachineTest, TestBeginFrameWhenInvisibleAndForceCommit) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
diff --git a/cc/test/fake_content_layer_impl.cc b/cc/test/fake_content_layer_impl.cc
index b1c01f1..5f72668 100644
--- a/cc/test/fake_content_layer_impl.cc
+++ b/cc/test/fake_content_layer_impl.cc
@@ -13,11 +13,17 @@ FakeContentLayerImpl::FakeContentLayerImpl(LayerTreeImpl* tree_impl, int id)
FakeContentLayerImpl::~FakeContentLayerImpl() {}
+scoped_ptr<LayerImpl> FakeContentLayerImpl::CreateLayerImpl(
+ LayerTreeImpl* tree_impl) {
+ return FakeContentLayerImpl::Create(tree_impl, id()).PassAs<LayerImpl>();
+}
+
bool FakeContentLayerImpl::HaveResourceForTileAt(int i, int j) {
return HasResourceIdForTileAt(i, j);
}
void FakeContentLayerImpl::DidLoseOutputSurface() {
+ TiledLayerImpl::DidLoseOutputSurface();
++lost_output_surface_count_;
}
diff --git a/cc/test/fake_content_layer_impl.h b/cc/test/fake_content_layer_impl.h
index b05a5de..74c4eda 100644
--- a/cc/test/fake_content_layer_impl.h
+++ b/cc/test/fake_content_layer_impl.h
@@ -18,6 +18,9 @@ class FakeContentLayerImpl : public TiledLayerImpl {
}
virtual ~FakeContentLayerImpl();
+ virtual scoped_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl)
+ OVERRIDE;
+
bool HaveResourceForTileAt(int i, int j);
size_t lost_output_surface_count() const {
diff --git a/cc/test/fake_layer_tree_host_impl_client.h b/cc/test/fake_layer_tree_host_impl_client.h
index 7e35a20..abcebf1 100644
--- a/cc/test/fake_layer_tree_host_impl_client.h
+++ b/cc/test/fake_layer_tree_host_impl_client.h
@@ -39,6 +39,7 @@ class FakeLayerTreeHostImplClient : public LayerTreeHostImplClient {
OVERRIDE {}
virtual void DidReceiveLastInputEventForVSync(base::TimeTicks frame_time)
OVERRIDE {}
+ virtual void DidActivatePendingTree() OVERRIDE {}
};
} // namespace cc
diff --git a/cc/test/layer_tree_pixel_test.cc b/cc/test/layer_tree_pixel_test.cc
index 27dd3e7..6f7ab2f 100644
--- a/cc/test/layer_tree_pixel_test.cc
+++ b/cc/test/layer_tree_pixel_test.cc
@@ -118,7 +118,7 @@ void LayerTreePixelTest::RunPixelTest(
content_root_ = content_root;
readback_target_ = NULL;
ref_file_ = file_name;
- RunTest(true, false);
+ RunTest(true, false, true);
}
void LayerTreePixelTest::RunPixelTestWithReadbackTarget(
@@ -128,7 +128,7 @@ void LayerTreePixelTest::RunPixelTestWithReadbackTarget(
content_root_ = content_root;
readback_target_ = target;
ref_file_ = file_name;
- RunTest(true, false);
+ RunTest(true, false, true);
}
void LayerTreePixelTest::SetupTree() {
diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc
index 22de2d8..95ee7b2 100644
--- a/cc/test/layer_tree_test.cc
+++ b/cc/test/layer_tree_test.cc
@@ -298,6 +298,7 @@ LayerTreeTest::LayerTreeTest()
schedule_when_set_visible_true_(false),
started_(false),
ended_(false),
+ delegating_renderer_(false),
timeout_seconds_(0),
impl_thread_(NULL),
weak_factory_(this) {
@@ -535,7 +536,9 @@ void LayerTreeTest::DispatchComposite() {
layer_tree_host_->Composite(now);
}
-void LayerTreeTest::RunTest(bool threaded, bool delegating_renderer) {
+void LayerTreeTest::RunTest(bool threaded,
+ bool delegating_renderer,
+ bool impl_side_painting) {
if (threaded) {
impl_thread_.reset(new base::Thread("Compositor"));
ASSERT_TRUE(impl_thread_->Start());
@@ -547,6 +550,11 @@ void LayerTreeTest::RunTest(bool threaded, bool delegating_renderer) {
// Spend less time waiting for vsync because the output is mocked out.
settings_.refresh_rate = 200.0;
+ if (impl_side_painting) {
+ DCHECK(threaded) <<
+ "Don't run single thread + impl side painting, it doesn't exist.";
+ settings_.impl_side_painting = true;
+ }
InitializeSettings(&settings_);
main_ccthread_->PostTask(
diff --git a/cc/test/layer_tree_test.h b/cc/test/layer_tree_test.h
index 4d5758a..c7072da 100644
--- a/cc/test/layer_tree_test.h
+++ b/cc/test/layer_tree_test.h
@@ -135,7 +135,9 @@ class LayerTreeTest : public testing::Test, public TestHooks {
void DispatchComposite();
void DispatchDidAddAnimation();
- virtual void RunTest(bool threaded, bool delegating_renderer);
+ virtual void RunTest(bool threaded,
+ bool delegating_renderer,
+ bool impl_side_painting);
Thread* ImplThread() { return proxy() ? proxy()->ImplThread() : NULL; }
Proxy* proxy() const {
@@ -182,13 +184,13 @@ class LayerTreeTest : public testing::Test, public TestHooks {
#define SINGLE_THREAD_DIRECT_RENDERER_TEST_F(TEST_FIXTURE_NAME) \
TEST_F(TEST_FIXTURE_NAME, RunSingleThread_DirectRenderer) { \
- RunTest(false, false); \
+ RunTest(false, false, false); \
} \
class SingleThreadDirectNeedsSemicolon##TEST_FIXTURE_NAME {}
#define SINGLE_THREAD_DELEGATING_RENDERER_TEST_F(TEST_FIXTURE_NAME) \
TEST_F(TEST_FIXTURE_NAME, RunSingleThread_DelegatingRenderer) { \
- RunTest(false, true); \
+ RunTest(false, true, false); \
} \
class SingleThreadDelegatingNeedsSemicolon##TEST_FIXTURE_NAME {}
@@ -196,16 +198,24 @@ class LayerTreeTest : public testing::Test, public TestHooks {
SINGLE_THREAD_DIRECT_RENDERER_TEST_F(TEST_FIXTURE_NAME); \
SINGLE_THREAD_DELEGATING_RENDERER_TEST_F(TEST_FIXTURE_NAME)
-#define MULTI_THREAD_DIRECT_RENDERER_TEST_F(TEST_FIXTURE_NAME) \
- TEST_F(TEST_FIXTURE_NAME, RunMultiThread_DirectRenderer) { \
- RunTest(true, false); \
- } \
+#define MULTI_THREAD_DIRECT_RENDERER_TEST_F(TEST_FIXTURE_NAME) \
+ TEST_F(TEST_FIXTURE_NAME, RunMultiThread_DirectRenderer_MainThreadPaint) { \
+ RunTest(true, false, false); \
+ } \
+ TEST_F(TEST_FIXTURE_NAME, RunMultiThread_DirectRenderer_ImplSidePaint) { \
+ RunTest(true, false, true); \
+ } \
class MultiThreadDirectNeedsSemicolon##TEST_FIXTURE_NAME {}
#define MULTI_THREAD_DELEGATING_RENDERER_TEST_F(TEST_FIXTURE_NAME) \
- TEST_F(TEST_FIXTURE_NAME, RunMultiThread_DelegatingRenderer) { \
- RunTest(true, true); \
- } \
+ TEST_F(TEST_FIXTURE_NAME, \
+ RunMultiThread_DelegatingRenderer_MainThreadPaint) { \
+ RunTest(true, true, false); \
+ } \
+ TEST_F(TEST_FIXTURE_NAME, \
+ RunMultiThread_DelegatingRenderer_ImplSidePaint) { \
+ RunTest(true, true, true); \
+ } \
class MultiThreadDelegatingNeedsSemicolon##TEST_FIXTURE_NAME {}
#define MULTI_THREAD_TEST_F(TEST_FIXTURE_NAME) \
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index efcc529..c9db433 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -1334,6 +1334,8 @@ void LayerTreeHostImpl::ActivatePendingTree() {
stats.total_paint_time + stats.total_record_time +
stats.total_rasterize_time_for_now_bins_on_pending_tree);
}
+
+ client_->DidActivatePendingTree();
}
void LayerTreeHostImpl::SetVisible(bool visible) {
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h
index f5befeb..5125c82 100644
--- a/cc/trees/layer_tree_host_impl.h
+++ b/cc/trees/layer_tree_host_impl.h
@@ -75,6 +75,7 @@ class LayerTreeHostImplClient {
virtual void RenewTreePriority() = 0;
virtual void RequestScrollbarAnimationOnImplThread(base::TimeDelta delay) = 0;
virtual void DidReceiveLastInputEventForVSync(base::TimeTicks frame_time) = 0;
+ virtual void DidActivatePendingTree() = 0;
protected:
virtual ~LayerTreeHostImplClient() {}
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc
index ac11f63..fb5a2c4 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -131,6 +131,7 @@ class LayerTreeHostImplTest : public testing::Test,
OVERRIDE {}
virtual void DidReceiveLastInputEventForVSync(base::TimeTicks frame_time)
OVERRIDE {}
+ virtual void DidActivatePendingTree() OVERRIDE {}
void set_reduce_memory_result(bool reduce_memory_result) {
reduce_memory_result_ = reduce_memory_result;
diff --git a/cc/trees/layer_tree_host_perftest.cc b/cc/trees/layer_tree_host_perftest.cc
index 040b32b..ca24016 100644
--- a/cc/trees/layer_tree_host_perftest.cc
+++ b/cc/trees/layer_tree_host_perftest.cc
@@ -131,7 +131,7 @@ class LayerTreeHostPerfTestJsonReader : public LayerTreeHostPerfTest {
// Simulates a tab switcher scene with two stacks of 10 tabs each.
TEST_F(LayerTreeHostPerfTestJsonReader, TenTenSingleThread) {
ReadTestFile("10_10_layer_tree");
- RunTest(false, false);
+ RunTest(false, false, false);
}
// Simulates a tab switcher scene with two stacks of 10 tabs each.
@@ -139,7 +139,7 @@ TEST_F(LayerTreeHostPerfTestJsonReader,
TenTenSingleThread_FullDamageEachFrame) {
full_damage_each_frame_ = true;
ReadTestFile("10_10_layer_tree");
- RunTest(false, false);
+ RunTest(false, false, false);
}
// Simulates main-thread scrolling on each frame.
@@ -166,18 +166,13 @@ class ScrollingLayerTreePerfTest : public LayerTreeHostPerfTestJsonReader {
TEST_F(ScrollingLayerTreePerfTest, LongScrollablePage) {
ReadTestFile("long_scrollable_page");
- RunTest(false, false);
+ RunTest(false, false, false);
}
-// Simulates impl-side painting.
class ImplSidePaintingPerfTest : public LayerTreeHostPerfTestJsonReader {
- public:
- ImplSidePaintingPerfTest()
- : LayerTreeHostPerfTestJsonReader() {}
-
- virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
- settings->impl_side_painting = true;
- }
+ protected:
+ // Run test with impl-side painting.
+ void RunTestWithImplSidePainting() { RunTest(true, false, true); }
};
// Simulates a page with several large, transformed and animated layers.
@@ -185,7 +180,7 @@ TEST_F(ImplSidePaintingPerfTest, HeavyPage) {
animation_driven_drawing_ = true;
measure_commit_cost_ = true;
ReadTestFile("heavy_layer_tree");
- RunTest(true, false);
+ RunTestWithImplSidePainting();
}
} // namespace
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc
index 4591f14..2aac01e 100644
--- a/cc/trees/layer_tree_host_unittest.cc
+++ b/cc/trees/layer_tree_host_unittest.cc
@@ -119,7 +119,7 @@ class LayerTreeHostTestSetNeedsCommit1 : public LayerTreeHostTest {
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit1);
-// A setNeedsCommit should lead to 1 commit. Issuing a second commit after that
+// A SetNeedsCommit should lead to 1 commit. Issuing a second commit after that
// first committed frame draws should lead to another commit.
class LayerTreeHostTestSetNeedsCommit2 : public LayerTreeHostTest {
public:
@@ -133,10 +133,16 @@ class LayerTreeHostTestSetNeedsCommit2 : public LayerTreeHostTest {
virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
++num_commits_;
- if (impl->active_tree()->source_frame_number() == 0)
- PostSetNeedsCommitToMainThread();
- else if (impl->active_tree()->source_frame_number() == 1)
- EndTest();
+ switch (num_commits_) {
+ case 1:
+ PostSetNeedsCommitToMainThread();
+ break;
+ case 2:
+ EndTest();
+ break;
+ default:
+ NOTREACHED();
+ }
}
virtual void AfterTest() OVERRIDE {
@@ -607,7 +613,7 @@ class LayerTreeHostTestCommit : public LayerTreeHostTest {
PostSetNeedsCommitToMainThread();
}
- virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
+ virtual void TreeActivatedOnThread(LayerTreeHostImpl* impl) OVERRIDE {
EXPECT_EQ(gfx::Size(20, 20), impl->device_viewport_size());
EXPECT_EQ(SK_ColorGRAY, impl->active_tree()->background_color());
EXPECT_EQ(5.f, impl->active_tree()->page_scale_factor());
@@ -626,36 +632,62 @@ class LayerTreeHostTestStartPageScaleAnimation : public LayerTreeHostTest {
public:
LayerTreeHostTestStartPageScaleAnimation() {}
+ virtual void SetupTree() OVERRIDE {
+ LayerTreeHostTest::SetupTree();
+
+ scroll_layer_ = FakeContentLayer::Create(&client_);
+ scroll_layer_->SetScrollable(true);
+ scroll_layer_->SetScrollOffset(gfx::Vector2d());
+ layer_tree_host()->root_layer()->AddChild(scroll_layer_);
+ }
+
virtual void BeginTest() OVERRIDE {
- layer_tree_host()->root_layer()->SetScrollable(true);
- layer_tree_host()->root_layer()->SetScrollOffset(gfx::Vector2d());
- layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.5f, 2.f);
- layer_tree_host()->StartPageScaleAnimation(
- gfx::Vector2d(), false, 1.25f, base::TimeDelta());
PostSetNeedsCommitToMainThread();
- PostSetNeedsRedrawToMainThread();
}
virtual void ApplyScrollAndScale(gfx::Vector2d scroll_delta, float scale)
OVERRIDE {
- gfx::Vector2d offset = layer_tree_host()->root_layer()->scroll_offset();
- layer_tree_host()->root_layer()->SetScrollOffset(offset + scroll_delta);
+ gfx::Vector2d offset = scroll_layer_->scroll_offset();
+ scroll_layer_->SetScrollOffset(offset + scroll_delta);
layer_tree_host()->SetPageScaleFactorAndLimits(scale, 0.5f, 2.f);
}
- virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
+ virtual void TreeActivatedOnThread(LayerTreeHostImpl* impl) OVERRIDE {
impl->ProcessScrollDeltas();
// We get one commit before the first draw, and the animation doesn't happen
// until the second draw.
- if (impl->active_tree()->source_frame_number() == 1) {
- EXPECT_EQ(1.25f, impl->active_tree()->page_scale_factor());
- EndTest();
- } else {
- PostSetNeedsRedrawToMainThread();
+ switch (impl->active_tree()->source_frame_number()) {
+ case 0:
+ EXPECT_EQ(1.f, impl->active_tree()->page_scale_factor());
+ // We'll start an animation when we get back to the main thread.
+ break;
+ case 1:
+ EXPECT_EQ(1.f, impl->active_tree()->page_scale_factor());
+ PostSetNeedsRedrawToMainThread();
+ break;
+ case 2:
+ EXPECT_EQ(1.25f, impl->active_tree()->page_scale_factor());
+ EndTest();
+ break;
+ default:
+ NOTREACHED();
+ }
+ }
+
+ virtual void DidCommitAndDrawFrame() OVERRIDE {
+ switch (layer_tree_host()->commit_number()) {
+ case 1:
+ layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.5f, 2.f);
+ layer_tree_host()->StartPageScaleAnimation(
+ gfx::Vector2d(), false, 1.25f, base::TimeDelta());
+ break;
}
}
virtual void AfterTest() OVERRIDE {}
+
+ FakeContentLayerClient client_;
+ scoped_refptr<FakeContentLayer> scroll_layer_;
};
MULTI_THREAD_TEST_F(LayerTreeHostTestStartPageScaleAnimation);
@@ -824,7 +856,7 @@ class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers
PostSetNeedsCommitToMainThread();
}
- virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
+ virtual void TreeActivatedOnThread(LayerTreeHostImpl* impl) OVERRIDE {
// Should only do one commit.
EXPECT_EQ(0, impl->active_tree()->source_frame_number());
// Device scale factor should come over to impl.
@@ -929,7 +961,7 @@ class LayerTreeHostTestAtomicCommit : public LayerTreeHostTest {
virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
- virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
+ virtual void TreeActivatedOnThread(LayerTreeHostImpl* impl) OVERRIDE {
ASSERT_EQ(0u, layer_tree_host()->settings().max_partial_texture_updates);
TestWebGraphicsContext3D* context = static_cast<TestWebGraphicsContext3D*>(
@@ -1025,6 +1057,8 @@ class LayerTreeHostTestAtomicCommitWithPartialUpdate
settings->max_partial_texture_updates = 1;
// Linear fade animator prevents scrollbars from drawing immediately.
settings->use_linear_fade_scrollbar_animator = false;
+ // No partial updates when impl side painting is enabled.
+ settings->impl_side_painting = false;
}
virtual void SetupTree() OVERRIDE {
@@ -1930,11 +1964,11 @@ class LayerTreeHostTestMaxPendingFrames : public LayerTreeHostTest {
};
TEST_F(LayerTreeHostTestMaxPendingFrames, DelegatingRenderer) {
- RunTest(true, true);
+ RunTest(true, true, true);
}
TEST_F(LayerTreeHostTestMaxPendingFrames, GLRenderer) {
- RunTest(true, false);
+ RunTest(true, false, true);
}
class LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted
@@ -1969,7 +2003,7 @@ class LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted
EndTest();
}
- virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
+ virtual void TreeActivatedOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
++num_commits_;
switch (num_commits_) {
case 1:
@@ -2702,22 +2736,36 @@ class LayerTreeHostTestAsyncReadback : public LayerTreeHostTest {
// Readback can't be done with a delegating renderer.
TEST_F(LayerTreeHostTestAsyncReadback, GLRenderer_RunSingleThread) {
use_gl_renderer_ = true;
- RunTest(false, false);
+ RunTest(false, false, false);
}
-TEST_F(LayerTreeHostTestAsyncReadback, GLRenderer_RunMultiThread) {
+TEST_F(LayerTreeHostTestAsyncReadback,
+ GLRenderer_RunMultiThread_MainThreadPainting) {
use_gl_renderer_ = true;
- RunTest(true, false);
+ RunTest(true, false, false);
+}
+
+TEST_F(LayerTreeHostTestAsyncReadback,
+ GLRenderer_RunMultiThread_ImplSidePainting) {
+ use_gl_renderer_ = true;
+ RunTest(true, false, true);
}
TEST_F(LayerTreeHostTestAsyncReadback, SoftwareRenderer_RunSingleThread) {
use_gl_renderer_ = false;
- RunTest(false, false);
+ RunTest(false, false, false);
+}
+
+TEST_F(LayerTreeHostTestAsyncReadback,
+ SoftwareRenderer_RunMultiThread_MainThreadPainting) {
+ use_gl_renderer_ = false;
+ RunTest(true, false, false);
}
-TEST_F(LayerTreeHostTestAsyncReadback, SoftwareRenderer_RunMultiThread) {
+TEST_F(LayerTreeHostTestAsyncReadback,
+ SoftwareRenderer_RunMultiThread_ImplSidePainting) {
use_gl_renderer_ = false;
- RunTest(true, false);
+ RunTest(true, false, true);
}
class LayerTreeHostTestAsyncReadbackLayerDestroyed : public LayerTreeHostTest {
@@ -2878,11 +2926,11 @@ class LayerTreeHostTestNumFramesPending : public LayerTreeHostTest {
};
TEST_F(LayerTreeHostTestNumFramesPending, DelegatingRenderer) {
- RunTest(true, true);
+ RunTest(true, true, true);
}
TEST_F(LayerTreeHostTestNumFramesPending, GLRenderer) {
- RunTest(true, false);
+ RunTest(true, false, true);
}
} // namespace
diff --git a/cc/trees/layer_tree_host_unittest_animation.cc b/cc/trees/layer_tree_host_unittest_animation.cc
index aa8843d..742c00c 100644
--- a/cc/trees/layer_tree_host_unittest_animation.cc
+++ b/cc/trees/layer_tree_host_unittest_animation.cc
@@ -462,7 +462,7 @@ class LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity
PostAddAnimationToMainThread(update_check_layer_.get());
}
- virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
+ virtual void TreeActivatedOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
LayerAnimationController* controller_impl =
host_impl->active_tree()->root_layer()->layer_animation_controller();
Animation* animation_impl =
@@ -731,6 +731,7 @@ class LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations
}
virtual void BeginTest() OVERRIDE {
+ prevented_draw_ = 0;
added_animations_ = 0;
started_times_ = 0;
finished_times_ = 0;
@@ -750,7 +751,10 @@ class LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations
bool result) OVERRIDE {
if (added_animations_ < 2)
return result;
+ if (TestEnded())
+ return result;
// Act like there is checkerboard when the second animation wants to draw.
+ ++prevented_draw_;
return false;
}
@@ -766,12 +770,12 @@ class LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations
AddAnimatedTransformToLayer(content_, 0.1, 5, 5);
added_animations_++;
break;
- case 3:
- break;
}
}
virtual void notifyAnimationStarted(double wall_clock_time) OVERRIDE {
+ if (TestEnded())
+ return;
started_times_++;
}
@@ -784,6 +788,8 @@ class LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations
}
virtual void AfterTest() OVERRIDE {
+ // Make sure we tried to draw the second animation but failed.
+ EXPECT_LT(0, prevented_draw_);
// The first animation should be started, but the second should not because
// of checkerboard.
EXPECT_EQ(1, started_times_);
@@ -791,6 +797,7 @@ class LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations
EXPECT_EQ(1, finished_times_);
}
+ int prevented_draw_;
int added_animations_;
int started_times_;
int finished_times_;
diff --git a/cc/trees/layer_tree_host_unittest_context.cc b/cc/trees/layer_tree_host_unittest_context.cc
index 198907d..2784cd8 100644
--- a/cc/trees/layer_tree_host_unittest_context.cc
+++ b/cc/trees/layer_tree_host_unittest_context.cc
@@ -486,38 +486,56 @@ class LayerTreeHostContextTestLostContextSucceedsWithContent
TEST_F(LayerTreeHostContextTestLostContextSucceedsWithContent,
NoSurface_SingleThread_DirectRenderer) {
use_surface_ = false;
- RunTest(false, false);
+ RunTest(false, false, false);
}
TEST_F(LayerTreeHostContextTestLostContextSucceedsWithContent,
NoSurface_SingleThread_DelegatingRenderer) {
use_surface_ = false;
- RunTest(false, true);
+ RunTest(false, true, false);
}
TEST_F(LayerTreeHostContextTestLostContextSucceedsWithContent,
- NoSurface_MultiThread_DirectRenderer) {
+ NoSurface_MultiThread_DirectRenderer_MainThreadPaint) {
use_surface_ = false;
- RunTest(true, false);
+ RunTest(true, false, false);
}
TEST_F(LayerTreeHostContextTestLostContextSucceedsWithContent,
- NoSurface_MultiThread_DelegatingRenderer) {
+ NoSurface_MultiThread_DirectRenderer_ImplSidePaint) {
use_surface_ = false;
- RunTest(true, true);
+ RunTest(true, false, true);
+}
+
+TEST_F(LayerTreeHostContextTestLostContextSucceedsWithContent,
+ NoSurface_MultiThread_DelegatingRenderer_MainThreadPaint) {
+ use_surface_ = false;
+ RunTest(true, true, false);
+}
+
+TEST_F(LayerTreeHostContextTestLostContextSucceedsWithContent,
+ NoSurface_MultiThread_DelegatingRenderer_ImplSidePaint) {
+ use_surface_ = false;
+ RunTest(true, true, true);
}
// Surfaces don't exist with a delegating renderer.
TEST_F(LayerTreeHostContextTestLostContextSucceedsWithContent,
WithSurface_SingleThread_DirectRenderer) {
use_surface_ = true;
- RunTest(false, false);
+ RunTest(false, false, false);
}
TEST_F(LayerTreeHostContextTestLostContextSucceedsWithContent,
- WithSurface_MultiThread_DirectRenderer) {
+ WithSurface_MultiThread_DirectRenderer_MainThreadPaint) {
use_surface_ = true;
- RunTest(true, false);
+ RunTest(true, false, false);
+}
+
+TEST_F(LayerTreeHostContextTestLostContextSucceedsWithContent,
+ WithSurface_MultiThread_DirectRenderer_ImplSidePaint) {
+ use_surface_ = true;
+ RunTest(true, false, true);
}
class LayerTreeHostContextTestOffscreenContextFails
@@ -624,7 +642,7 @@ TEST_F(LayerTreeHostContextTestLostContextFails,
times_to_fail_reinitialize_ = 100;
times_to_fail_recreate_ = 0;
times_to_lose_on_recreate_ = 0;
- RunTest(false, false);
+ RunTest(false, false, false);
}
TEST_F(LayerTreeHostContextTestLostContextFails,
@@ -632,23 +650,39 @@ TEST_F(LayerTreeHostContextTestLostContextFails,
times_to_fail_reinitialize_ = 100;
times_to_fail_recreate_ = 0;
times_to_lose_on_recreate_ = 0;
- RunTest(false, true);
+ RunTest(false, true, false);
}
TEST_F(LayerTreeHostContextTestLostContextFails,
- FailReinitialize100_MultiThread_DirectRenderer) {
+ FailReinitialize100_MultiThread_DirectRenderer_MainThreadPaint) {
times_to_fail_reinitialize_ = 100;
times_to_fail_recreate_ = 0;
times_to_lose_on_recreate_ = 0;
- RunTest(true, false);
+ RunTest(true, false, false);
}
TEST_F(LayerTreeHostContextTestLostContextFails,
- FailReinitialize100_MultiThread_DelegatingRenderer) {
+ FailReinitialize100_MultiThread_DirectRenderer_ImplSidePaint) {
times_to_fail_reinitialize_ = 100;
times_to_fail_recreate_ = 0;
times_to_lose_on_recreate_ = 0;
- RunTest(true, true);
+ RunTest(true, false, true);
+}
+
+TEST_F(LayerTreeHostContextTestLostContextFails,
+ FailReinitialize100_MultiThread_DelegatingRenderer_MainThreadPaint) {
+ times_to_fail_reinitialize_ = 100;
+ times_to_fail_recreate_ = 0;
+ times_to_lose_on_recreate_ = 0;
+ RunTest(true, true, false);
+}
+
+TEST_F(LayerTreeHostContextTestLostContextFails,
+ FailReinitialize100_MultiThread_DelegatingRenderer_ImplSidePaint) {
+ times_to_fail_reinitialize_ = 100;
+ times_to_fail_recreate_ = 0;
+ times_to_lose_on_recreate_ = 0;
+ RunTest(true, true, true);
}
TEST_F(LayerTreeHostContextTestLostContextFails,
@@ -656,7 +690,7 @@ TEST_F(LayerTreeHostContextTestLostContextFails,
times_to_fail_reinitialize_ = 0;
times_to_fail_recreate_ = 100;
times_to_lose_on_recreate_ = 0;
- RunTest(false, false);
+ RunTest(false, false, false);
}
TEST_F(LayerTreeHostContextTestLostContextFails,
@@ -664,23 +698,39 @@ TEST_F(LayerTreeHostContextTestLostContextFails,
times_to_fail_reinitialize_ = 0;
times_to_fail_recreate_ = 100;
times_to_lose_on_recreate_ = 0;
- RunTest(false, true);
+ RunTest(false, true, false);
+}
+
+TEST_F(LayerTreeHostContextTestLostContextFails,
+ FailRecreate100_MultiThread_DirectRenderer_MainThreadPaint) {
+ times_to_fail_reinitialize_ = 0;
+ times_to_fail_recreate_ = 100;
+ times_to_lose_on_recreate_ = 0;
+ RunTest(true, false, false);
+}
+
+TEST_F(LayerTreeHostContextTestLostContextFails,
+ FailRecreate100_MultiThread_DirectRenderer_ImplSidePaint) {
+ times_to_fail_reinitialize_ = 0;
+ times_to_fail_recreate_ = 100;
+ times_to_lose_on_recreate_ = 0;
+ RunTest(true, false, true);
}
TEST_F(LayerTreeHostContextTestLostContextFails,
- FailRecreate100_MultiThread_DirectRenderer) {
+ FailRecreate100_MultiThread_DelegatingRenderer_MainThreadPaint) {
times_to_fail_reinitialize_ = 0;
times_to_fail_recreate_ = 100;
times_to_lose_on_recreate_ = 0;
- RunTest(true, false);
+ RunTest(true, true, false);
}
TEST_F(LayerTreeHostContextTestLostContextFails,
- FailRecreate100_MultiThread_DelegatingRenderer) {
+ FailRecreate100_MultiThread_DelegatingRenderer_ImplSidePaint) {
times_to_fail_reinitialize_ = 0;
times_to_fail_recreate_ = 100;
times_to_lose_on_recreate_ = 0;
- RunTest(true, true);
+ RunTest(true, true, true);
}
TEST_F(LayerTreeHostContextTestLostContextFails,
@@ -688,7 +738,7 @@ TEST_F(LayerTreeHostContextTestLostContextFails,
times_to_fail_reinitialize_ = 0;
times_to_fail_recreate_ = 0;
times_to_lose_on_recreate_ = 100;
- RunTest(false, false);
+ RunTest(false, false, false);
}
TEST_F(LayerTreeHostContextTestLostContextFails,
@@ -696,23 +746,39 @@ TEST_F(LayerTreeHostContextTestLostContextFails,
times_to_fail_reinitialize_ = 0;
times_to_fail_recreate_ = 0;
times_to_lose_on_recreate_ = 100;
- RunTest(false, true);
+ RunTest(false, true, false);
+}
+
+TEST_F(LayerTreeHostContextTestLostContextFails,
+ LoseOnRecreate100_MultiThread_DirectRenderer_MainThreadPaint) {
+ times_to_fail_reinitialize_ = 0;
+ times_to_fail_recreate_ = 0;
+ times_to_lose_on_recreate_ = 100;
+ RunTest(true, false, false);
}
TEST_F(LayerTreeHostContextTestLostContextFails,
- LoseOnRecreate100_MultiThread_DirectRenderer) {
+ LoseOnRecreate100_MultiThread_DirectRenderer_ImplSidePaint) {
times_to_fail_reinitialize_ = 0;
times_to_fail_recreate_ = 0;
times_to_lose_on_recreate_ = 100;
- RunTest(true, false);
+ RunTest(true, false, true);
}
TEST_F(LayerTreeHostContextTestLostContextFails,
- LoseOnRecreate100_MultiThread_DelegatingRenderer) {
+ LoseOnRecreate100_MultiThread_DelegatingRenderer_MainThreadPaint) {
times_to_fail_reinitialize_ = 0;
times_to_fail_recreate_ = 0;
times_to_lose_on_recreate_ = 100;
- RunTest(true, true);
+ RunTest(true, true, false);
+}
+
+TEST_F(LayerTreeHostContextTestLostContextFails,
+ LoseOnRecreate100_MultiThread_DelegatingRenderer_ImplSidePaint) {
+ times_to_fail_reinitialize_ = 0;
+ times_to_fail_recreate_ = 0;
+ times_to_lose_on_recreate_ = 100;
+ RunTest(true, true, true);
}
class LayerTreeHostContextTestFinishAllRenderingAfterLoss
@@ -818,49 +884,73 @@ class LayerTreeHostContextTestLostContextAndEvictTextures
TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures,
LoseAfterEvict_SingleThread_DirectRenderer) {
lose_after_evict_ = true;
- RunTest(false, false);
+ RunTest(false, false, false);
}
TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures,
LoseAfterEvict_SingleThread_DelegatingRenderer) {
lose_after_evict_ = true;
- RunTest(false, true);
+ RunTest(false, true, false);
}
TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures,
- LoseAfterEvict_MultiThread_DirectRenderer) {
+ LoseAfterEvict_MultiThread_DirectRenderer_MainThreadPaint) {
lose_after_evict_ = true;
- RunTest(true, false);
+ RunTest(true, false, false);
}
TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures,
- LoseAfterEvict_MultiThread_DelegatingRenderer) {
+ LoseAfterEvict_MultiThread_DirectRenderer_ImplSidePaint) {
lose_after_evict_ = true;
- RunTest(true, true);
+ RunTest(true, false, true);
+}
+
+TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures,
+ LoseAfterEvict_MultiThread_DelegatingRenderer_MainThreadPaint) {
+ lose_after_evict_ = true;
+ RunTest(true, true, false);
+}
+
+TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures,
+ LoseAfterEvict_MultiThread_DelegatingRenderer_ImplSidePaint) {
+ lose_after_evict_ = true;
+ RunTest(true, true, true);
}
TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures,
LoseBeforeEvict_SingleThread_DirectRenderer) {
lose_after_evict_ = false;
- RunTest(false, false);
+ RunTest(false, false, false);
}
TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures,
LoseBeforeEvict_SingleThread_DelegatingRenderer) {
lose_after_evict_ = false;
- RunTest(false, true);
+ RunTest(false, true, false);
+}
+
+TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures,
+ LoseBeforeEvict_MultiThread_DirectRenderer_MainThreadPaint) {
+ lose_after_evict_ = false;
+ RunTest(true, false, false);
+}
+
+TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures,
+ LoseBeforeEvict_MultiThread_DirectRenderer_ImplSidePaint) {
+ lose_after_evict_ = false;
+ RunTest(true, false, true);
}
TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures,
- LoseBeforeEvict_MultiThread_DirectRenderer) {
+ LoseBeforeEvict_MultiThread_DelegatingRenderer_MainThreadPaint) {
lose_after_evict_ = false;
- RunTest(true, false);
+ RunTest(true, true, false);
}
TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures,
- LoseBeforeEvict_MultiThread_DelegatingRenderer) {
+ LoseBeforeEvict_MultiThread_DelegatingRenderer_ImplSidePaint) {
lose_after_evict_ = false;
- RunTest(true, true);
+ RunTest(true, true, true);
}
class LayerTreeHostContextTestLostContextWhileUpdatingResources
@@ -946,8 +1036,8 @@ class LayerTreeHostContextTestLayersNotified
PostSetNeedsCommitToMainThread();
}
- virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
- LayerTreeHostContextTest::CommitCompleteOnThread(host_impl);
+ virtual void TreeActivatedOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
+ LayerTreeHostContextTest::TreeActivatedOnThread(host_impl);
FakeContentLayerImpl* root = static_cast<FakeContentLayerImpl*>(
host_impl->active_tree()->root_layer());
@@ -1490,7 +1580,9 @@ class LayerTreeHostTestCannotCreateIfCannotCreateOutputSurface
return scoped_ptr<OutputSurface>();
}
- void RunTest(bool threaded, bool delegating_renderer) {
+ void RunTest(bool threaded,
+ bool delegating_renderer,
+ bool impl_side_painting) {
scoped_ptr<base::Thread> impl_thread;
scoped_ptr<cc::Thread> impl_ccthread(NULL);
if (threaded) {
@@ -1501,6 +1593,7 @@ class LayerTreeHostTestCannotCreateIfCannotCreateOutputSurface
}
LayerTreeSettings settings;
+ settings.impl_side_painting = impl_side_painting;
scoped_ptr<LayerTreeHost> layer_tree_host =
LayerTreeHost::Create(this, settings, impl_ccthread.Pass());
EXPECT_FALSE(layer_tree_host);
diff --git a/cc/trees/layer_tree_host_unittest_damage.cc b/cc/trees/layer_tree_host_unittest_damage.cc
index 1d5402c..0feabf7 100644
--- a/cc/trees/layer_tree_host_unittest_damage.cc
+++ b/cc/trees/layer_tree_host_unittest_damage.cc
@@ -147,6 +147,9 @@ class LayerTreeHostDamageTestNoDamageReadbackDoesDraw
break;
}
case 2:
+ // CompositeAndReadback causes a follow-up commit.
+ break;
+ case 3:
NOTREACHED();
break;
}
@@ -229,14 +232,16 @@ class LayerTreeHostDamageTestForcedFullDamage : public LayerTreeHostDamageTest {
child_damage_rect_ = gfx::RectF(10, 11, 12, 13);
break;
case 3:
- if (!delegating_renderer()) {
+ if (!delegating_renderer() &&
+ !host_impl->settings().impl_side_painting) {
// The update rect in the child should be damaged.
+ // TODO(danakj): Remove this when impl side painting is always on.
EXPECT_EQ(gfx::RectF(100+10, 100+11, 12, 13).ToString(),
root_damage.ToString());
} else {
- // When using a delegating renderer, the entire child is considered
- // damaged as we need to replace its resources with newly created
- // ones.
+ // When using a delegating renderer, or using impl side painting, the
+ // entire child is considered damaged as we need to replace its
+ // resources with newly created ones.
EXPECT_EQ(gfx::RectF(child_->position(), child_->bounds()).ToString(),
root_damage.ToString());
}
diff --git a/cc/trees/layer_tree_host_unittest_scroll.cc b/cc/trees/layer_tree_host_unittest_scroll.cc
index 6be91ea..493d1ca 100644
--- a/cc/trees/layer_tree_host_unittest_scroll.cc
+++ b/cc/trees/layer_tree_host_unittest_scroll.cc
@@ -334,7 +334,7 @@ class LayerTreeHostScrollTestCaseWithChild
}
}
- virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
+ virtual void TreeActivatedOnThread(LayerTreeHostImpl* impl) OVERRIDE {
LayerImpl* root_impl = impl->active_tree()->root_layer();
LayerImpl* root_scroll_layer_impl = root_impl->children()[0];
LayerImpl* child_layer_impl = root_scroll_layer_impl->children()[0];
@@ -451,87 +451,108 @@ class LayerTreeHostScrollTestCaseWithChild
};
TEST_F(LayerTreeHostScrollTestCaseWithChild,
- DeviceScaleFactor1_ScrollChild_DirectRenderer) {
+ DeviceScaleFactor1_ScrollChild_DirectRenderer_MainThreadPaint) {
+ device_scale_factor_ = 1.f;
+ scroll_child_layer_ = true;
+ RunTest(true, false, false);
+}
+
+TEST_F(LayerTreeHostScrollTestCaseWithChild,
+ DeviceScaleFactor1_ScrollChild_DirectRenderer_ImplSidePaint) {
+ device_scale_factor_ = 1.f;
+ scroll_child_layer_ = true;
+ RunTest(true, false, true);
+}
+
+TEST_F(LayerTreeHostScrollTestCaseWithChild,
+ DeviceScaleFactor1_ScrollChild_DelegatingRenderer_MainThreadPaint) {
device_scale_factor_ = 1.f;
scroll_child_layer_ = true;
- RunTest(true, false);
+ RunTest(true, true, false);
}
TEST_F(LayerTreeHostScrollTestCaseWithChild,
- DeviceScaleFactor1_ScrollChild_DelegatingRenderer) {
+ DeviceScaleFactor1_ScrollChild_DelegatingRenderer_ImplSidePaint) {
device_scale_factor_ = 1.f;
scroll_child_layer_ = true;
- RunTest(true, true);
+ RunTest(true, true, true);
}
TEST_F(LayerTreeHostScrollTestCaseWithChild,
DeviceScaleFactor15_ScrollChild_DirectRenderer) {
device_scale_factor_ = 1.5f;
scroll_child_layer_ = true;
- RunTest(true, false);
+ RunTest(true, false, true);
}
TEST_F(LayerTreeHostScrollTestCaseWithChild,
DeviceScaleFactor15_ScrollChild_DelegatingRenderer) {
device_scale_factor_ = 1.5f;
scroll_child_layer_ = true;
- RunTest(true, true);
+ RunTest(true, true, true);
}
TEST_F(LayerTreeHostScrollTestCaseWithChild,
DeviceScaleFactor2_ScrollChild_DirectRenderer) {
device_scale_factor_ = 2.f;
scroll_child_layer_ = true;
- RunTest(true, false);
+ RunTest(true, false, true);
}
TEST_F(LayerTreeHostScrollTestCaseWithChild,
DeviceScaleFactor2_ScrollChild_DelegatingRenderer) {
device_scale_factor_ = 2.f;
scroll_child_layer_ = true;
- RunTest(true, true);
+ RunTest(true, true, true);
}
TEST_F(LayerTreeHostScrollTestCaseWithChild,
DeviceScaleFactor1_ScrollRootScrollLayer_DirectRenderer) {
device_scale_factor_ = 1.f;
scroll_child_layer_ = false;
- RunTest(true, false);
+ RunTest(true, false, true);
}
TEST_F(LayerTreeHostScrollTestCaseWithChild,
DeviceScaleFactor1_ScrollRootScrollLayer_DelegatingRenderer) {
device_scale_factor_ = 1.f;
scroll_child_layer_ = false;
- RunTest(true, true);
+ RunTest(true, true, true);
}
TEST_F(LayerTreeHostScrollTestCaseWithChild,
DeviceScaleFactor15_ScrollRootScrollLayer_DirectRenderer) {
device_scale_factor_ = 1.5f;
scroll_child_layer_ = false;
- RunTest(true, false);
+ RunTest(true, false, true);
}
TEST_F(LayerTreeHostScrollTestCaseWithChild,
DeviceScaleFactor15_ScrollRootScrollLayer_DelegatingRenderer) {
device_scale_factor_ = 1.5f;
scroll_child_layer_ = false;
- RunTest(true, true);
+ RunTest(true, true, true);
+}
+
+TEST_F(LayerTreeHostScrollTestCaseWithChild,
+ DeviceScaleFactor2_ScrollRootScrollLayer_DirectRenderer_MainSidePaint) {
+ device_scale_factor_ = 2.f;
+ scroll_child_layer_ = false;
+ RunTest(true, false, false);
}
TEST_F(LayerTreeHostScrollTestCaseWithChild,
- DeviceScaleFactor2_ScrollRootScrollLayer_DirectRenderer) {
+ DeviceScaleFactor2_ScrollRootScrollLayer_DirectRenderer_ImplSidePaint) {
device_scale_factor_ = 2.f;
scroll_child_layer_ = false;
- RunTest(true, false);
+ RunTest(true, false, true);
}
TEST_F(LayerTreeHostScrollTestCaseWithChild,
DeviceScaleFactor2_ScrollRootScrollLayer_DelegatingRenderer) {
device_scale_factor_ = 2.f;
scroll_child_layer_ = false;
- RunTest(true, true);
+ RunTest(true, true, true);
}
class ImplSidePaintingScrollTest : public LayerTreeHostScrollTest {
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc
index 0c8d6c6..32cf649 100644
--- a/cc/trees/layer_tree_impl.cc
+++ b/cc/trees/layer_tree_impl.cc
@@ -315,6 +315,10 @@ static void ClearRenderSurfacesOnLayerImplRecursive(LayerImpl* current) {
}
void LayerTreeImpl::ClearRenderSurfaces() {
+ if (root_layer() == NULL) {
+ DCHECK(render_surface_layer_list_.empty());
+ return;
+ }
ClearRenderSurfacesOnLayerImplRecursive(root_layer());
render_surface_layer_list_.clear();
set_needs_update_draw_properties();
@@ -366,8 +370,12 @@ void LayerTreeImpl::UnregisterLayer(LayerImpl* layer) {
void LayerTreeImpl::PushPersistedState(LayerTreeImpl* pending_tree) {
int id = currently_scrolling_layer_ ? currently_scrolling_layer_->id() : 0;
- pending_tree->SetCurrentlyScrollingLayer(
- LayerTreeHostCommon::FindLayerInSubtree(pending_tree->root_layer(), id));
+ LayerImpl* pending_scrolling_layer_twin = NULL;
+ if (pending_tree->root_layer()) {
+ pending_scrolling_layer_twin =
+ LayerTreeHostCommon::FindLayerInSubtree(pending_tree->root_layer(), id);
+ }
+ pending_tree->SetCurrentlyScrollingLayer(pending_scrolling_layer_twin);
}
static void DidBecomeActiveRecursive(LayerImpl* layer) {
diff --git a/cc/trees/single_thread_proxy.h b/cc/trees/single_thread_proxy.h
index 6a2487b..1a11bb0 100644
--- a/cc/trees/single_thread_proxy.h
+++ b/cc/trees/single_thread_proxy.h
@@ -72,6 +72,7 @@ class SingleThreadProxy : public Proxy, LayerTreeHostImplClient {
OVERRIDE {}
virtual void DidReceiveLastInputEventForVSync(base::TimeTicks frame_time)
OVERRIDE {}
+ virtual void DidActivatePendingTree() OVERRIDE {}
// Called by the legacy path where RenderWidget does the scheduling.
void CompositeImmediately(base::TimeTicks frame_begin_time);
diff --git a/cc/trees/thread_proxy.cc b/cc/trees/thread_proxy.cc
index 86f4381..aff281f 100644
--- a/cc/trees/thread_proxy.cc
+++ b/cc/trees/thread_proxy.cc
@@ -736,7 +736,7 @@ void ThreadProxy::BeginFrame(
// point of view, but asynchronously performed on the impl thread,
// coordinated by the Scheduler.
{
- TRACE_EVENT0("cc", "commit");
+ TRACE_EVENT0("cc", "ThreadProxy::BeginFrame::commit");
DebugScopedSetMainThreadBlocked main_thread_blocked(this);
@@ -948,16 +948,6 @@ ThreadProxy::ScheduledActionDrawAndSwapInternal(bool forced_draw) {
layer_tree_host_impl_->UpdateAnimationState(start_ready_animations);
- // Check for tree activation.
- if (completion_event_for_commit_held_on_tree_activation_ &&
- !layer_tree_host_impl_->pending_tree()) {
- TRACE_EVENT_INSTANT0("cc", "ReleaseCommitbyActivation",
- TRACE_EVENT_SCOPE_THREAD);
- DCHECK(layer_tree_host_impl_->settings().impl_side_painting);
- completion_event_for_commit_held_on_tree_activation_->Signal();
- completion_event_for_commit_held_on_tree_activation_ = NULL;
- }
-
// Check for a pending CompositeAndReadback.
if (readback_request_on_impl_thread_) {
readback_request_on_impl_thread_->success = false;
@@ -1386,4 +1376,18 @@ void ThreadProxy::DidReceiveLastInputEventForVSync(
}
}
+void ThreadProxy::DidActivatePendingTree() {
+ DCHECK(IsImplThread());
+ TRACE_EVENT0("cc", "ThreadProxy::DidActivatePendingTreeOnImplThread");
+
+ if (completion_event_for_commit_held_on_tree_activation_ &&
+ !layer_tree_host_impl_->pending_tree()) {
+ TRACE_EVENT_INSTANT0("cc", "ReleaseCommitbyActivation",
+ TRACE_EVENT_SCOPE_THREAD);
+ DCHECK(layer_tree_host_impl_->settings().impl_side_painting);
+ completion_event_for_commit_held_on_tree_activation_->Signal();
+ completion_event_for_commit_held_on_tree_activation_ = NULL;
+ }
+}
+
} // namespace cc
diff --git a/cc/trees/thread_proxy.h b/cc/trees/thread_proxy.h
index ea42299..0360ca6 100644
--- a/cc/trees/thread_proxy.h
+++ b/cc/trees/thread_proxy.h
@@ -87,6 +87,7 @@ class ThreadProxy : public Proxy,
OVERRIDE;
virtual void DidReceiveLastInputEventForVSync(
base::TimeTicks frame_time) OVERRIDE;
+ virtual void DidActivatePendingTree() OVERRIDE;
// SchedulerClient implementation
virtual void ScheduledActionBeginFrame() OVERRIDE;