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
diff --git a/cc/layers/delegated_renderer_layer.cc b/cc/layers/delegated_renderer_layer.cc
index 81a9bdf..216d00d8 100644
--- a/cc/layers/delegated_renderer_layer.cc
+++ b/cc/layers/delegated_renderer_layer.cc
@@ -107,4 +107,12 @@
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 @@
// 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 @@
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 @@
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 @@
// 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 @@
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 @@
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..c70dd14a 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 @@
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 @@
// 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 @@
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 @@
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 @@
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 @@
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 48990cd5..56a90c8 100644
--- a/cc/quads/render_pass.cc
+++ b/cc/quads/render_pass.cc
@@ -21,8 +21,6 @@
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 df935aa8..63ba4149 100644
--- a/cc/scheduler/scheduler_state_machine.cc
+++ b/cc/scheduler/scheduler_state_machine.cc
@@ -429,7 +429,11 @@
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..117c7788 100644
--- a/cc/scheduler/scheduler_state_machine_unittest.cc
+++ b/cc/scheduler/scheduler_state_machine_unittest.cc
@@ -938,6 +938,28 @@
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() {}
+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 @@
}
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
// 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 @@
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 @@
#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 @@
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..c9db433d 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -1334,6 +1334,8 @@
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..5125c828 100644
--- a/cc/trees/layer_tree_host_impl.h
+++ b/cc/trees/layer_tree_host_impl.h
@@ -75,6 +75,7 @@
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 ac11f63f..fb5a2c4a 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -131,6 +131,7 @@
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 040b32bc..ca24016 100644
--- a/cc/trees/layer_tree_host_perftest.cc
+++ b/cc/trees/layer_tree_host_perftest.cc
@@ -131,7 +131,7 @@
// 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 @@
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 @@
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 @@
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..2aac01e0 100644
--- a/cc/trees/layer_tree_host_unittest.cc
+++ b/cc/trees/layer_tree_host_unittest.cc
@@ -119,7 +119,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
};
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 @@
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 @@
// 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) {
+TEST_F(LayerTreeHostTestAsyncReadback,
+ SoftwareRenderer_RunMultiThread_MainThreadPainting) {
use_gl_renderer_ = false;
- RunTest(true, false);
+ RunTest(true, false, false);
+}
+
+TEST_F(LayerTreeHostTestAsyncReadback,
+ SoftwareRenderer_RunMultiThread_ImplSidePainting) {
+ use_gl_renderer_ = false;
+ RunTest(true, false, true);
}
class LayerTreeHostTestAsyncReadbackLayerDestroyed : public LayerTreeHostTest {
@@ -2878,11 +2926,11 @@
};
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..742c00cb 100644
--- a/cc/trees/layer_tree_host_unittest_animation.cc
+++ b/cc/trees/layer_tree_host_unittest_animation.cc
@@ -462,7 +462,7 @@
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 @@
}
virtual void BeginTest() OVERRIDE {
+ prevented_draw_ = 0;
added_animations_ = 0;
started_times_ = 0;
finished_times_ = 0;
@@ -750,7 +751,10 @@
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 @@
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 @@
}
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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) {
+ FailRecreate100_MultiThread_DirectRenderer_MainThreadPaint) {
times_to_fail_reinitialize_ = 0;
times_to_fail_recreate_ = 100;
times_to_lose_on_recreate_ = 0;
- RunTest(true, false);
+ RunTest(true, false, false);
}
TEST_F(LayerTreeHostContextTestLostContextFails,
- FailRecreate100_MultiThread_DelegatingRenderer) {
+ FailRecreate100_MultiThread_DirectRenderer_ImplSidePaint) {
times_to_fail_reinitialize_ = 0;
times_to_fail_recreate_ = 100;
times_to_lose_on_recreate_ = 0;
- RunTest(true, true);
+ RunTest(true, false, true);
+}
+
+TEST_F(LayerTreeHostContextTestLostContextFails,
+ FailRecreate100_MultiThread_DelegatingRenderer_MainThreadPaint) {
+ times_to_fail_reinitialize_ = 0;
+ times_to_fail_recreate_ = 100;
+ times_to_lose_on_recreate_ = 0;
+ RunTest(true, true, false);
+}
+
+TEST_F(LayerTreeHostContextTestLostContextFails,
+ FailRecreate100_MultiThread_DelegatingRenderer_ImplSidePaint) {
+ times_to_fail_reinitialize_ = 0;
+ times_to_fail_recreate_ = 100;
+ times_to_lose_on_recreate_ = 0;
+ RunTest(true, true, true);
}
TEST_F(LayerTreeHostContextTestLostContextFails,
@@ -688,7 +738,7 @@
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 @@
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) {
+ LoseOnRecreate100_MultiThread_DirectRenderer_MainThreadPaint) {
times_to_fail_reinitialize_ = 0;
times_to_fail_recreate_ = 0;
times_to_lose_on_recreate_ = 100;
- RunTest(true, false);
+ RunTest(true, false, false);
}
TEST_F(LayerTreeHostContextTestLostContextFails,
- LoseOnRecreate100_MultiThread_DelegatingRenderer) {
+ LoseOnRecreate100_MultiThread_DirectRenderer_ImplSidePaint) {
times_to_fail_reinitialize_ = 0;
times_to_fail_recreate_ = 0;
times_to_lose_on_recreate_ = 100;
- RunTest(true, true);
+ RunTest(true, false, true);
+}
+
+TEST_F(LayerTreeHostContextTestLostContextFails,
+ LoseOnRecreate100_MultiThread_DelegatingRenderer_MainThreadPaint) {
+ times_to_fail_reinitialize_ = 0;
+ times_to_fail_recreate_ = 0;
+ times_to_lose_on_recreate_ = 100;
+ 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 @@
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) {
+ LoseBeforeEvict_MultiThread_DirectRenderer_MainThreadPaint) {
lose_after_evict_ = false;
- RunTest(true, false);
+ RunTest(true, false, false);
}
TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures,
- LoseBeforeEvict_MultiThread_DelegatingRenderer) {
+ LoseBeforeEvict_MultiThread_DirectRenderer_ImplSidePaint) {
lose_after_evict_ = false;
- RunTest(true, true);
+ RunTest(true, false, true);
+}
+
+TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures,
+ LoseBeforeEvict_MultiThread_DelegatingRenderer_MainThreadPaint) {
+ lose_after_evict_ = false;
+ RunTest(true, true, false);
+}
+
+TEST_F(LayerTreeHostContextTestLostContextAndEvictTextures,
+ LoseBeforeEvict_MultiThread_DelegatingRenderer_ImplSidePaint) {
+ lose_after_evict_ = false;
+ RunTest(true, true, true);
}
class LayerTreeHostContextTestLostContextWhileUpdatingResources
@@ -946,8 +1036,8 @@
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 @@
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 @@
}
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 @@
break;
}
case 2:
+ // CompositeAndReadback causes a follow-up commit.
+ break;
+ case 3:
NOTREACHED();
break;
}
@@ -229,14 +232,16 @@
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..493d1ca8 100644
--- a/cc/trees/layer_tree_host_unittest_scroll.cc
+++ b/cc/trees/layer_tree_host_unittest_scroll.cc
@@ -334,7 +334,7 @@
}
}
- 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 @@
};
TEST_F(LayerTreeHostScrollTestCaseWithChild,
- DeviceScaleFactor1_ScrollChild_DirectRenderer) {
+ DeviceScaleFactor1_ScrollChild_DirectRenderer_MainThreadPaint) {
device_scale_factor_ = 1.f;
scroll_child_layer_ = true;
- RunTest(true, false);
+ RunTest(true, false, false);
}
TEST_F(LayerTreeHostScrollTestCaseWithChild,
- DeviceScaleFactor1_ScrollChild_DelegatingRenderer) {
+ DeviceScaleFactor1_ScrollChild_DirectRenderer_ImplSidePaint) {
device_scale_factor_ = 1.f;
scroll_child_layer_ = true;
- RunTest(true, true);
+ RunTest(true, false, true);
+}
+
+TEST_F(LayerTreeHostScrollTestCaseWithChild,
+ DeviceScaleFactor1_ScrollChild_DelegatingRenderer_MainThreadPaint) {
+ device_scale_factor_ = 1.f;
+ scroll_child_layer_ = true;
+ RunTest(true, true, false);
+}
+
+TEST_F(LayerTreeHostScrollTestCaseWithChild,
+ DeviceScaleFactor1_ScrollChild_DelegatingRenderer_ImplSidePaint) {
+ device_scale_factor_ = 1.f;
+ scroll_child_layer_ = 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) {
+ DeviceScaleFactor2_ScrollRootScrollLayer_DirectRenderer_MainSidePaint) {
device_scale_factor_ = 2.f;
scroll_child_layer_ = false;
- RunTest(true, false);
+ RunTest(true, false, false);
+}
+
+TEST_F(LayerTreeHostScrollTestCaseWithChild,
+ DeviceScaleFactor2_ScrollRootScrollLayer_DirectRenderer_ImplSidePaint) {
+ device_scale_factor_ = 2.f;
+ scroll_child_layer_ = 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 @@
}
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::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 @@
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..aff281fb 100644
--- a/cc/trees/thread_proxy.cc
+++ b/cc/trees/thread_proxy.cc
@@ -736,7 +736,7 @@
// 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 @@
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::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 @@
OVERRIDE;
virtual void DidReceiveLastInputEventForVSync(
base::TimeTicks frame_time) OVERRIDE;
+ virtual void DidActivatePendingTree() OVERRIDE;
// SchedulerClient implementation
virtual void ScheduledActionBeginFrame() OVERRIDE;