summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cc/cc_tests.gyp1
-rw-r--r--cc/layers/delegated_renderer_layer_impl_unittest.cc46
-rw-r--r--cc/output/delegating_renderer_unittest.cc5
-rw-r--r--cc/test/fake_layer_tree_host_impl.h2
-rw-r--r--cc/test/layer_tree_test.cc17
-rw-r--r--cc/test/layer_tree_test.h2
-rw-r--r--cc/trees/damage_tracker.cc7
-rw-r--r--cc/trees/damage_tracker.h3
-rw-r--r--cc/trees/damage_tracker_unittest.cc29
-rw-r--r--cc/trees/layer_tree_host_impl.cc51
-rw-r--r--cc/trees/layer_tree_host_impl.h8
-rw-r--r--cc/trees/layer_tree_host_impl_unittest.cc264
-rw-r--r--cc/trees/layer_tree_host_perftest.cc14
-rw-r--r--cc/trees/layer_tree_host_unittest.cc54
-rw-r--r--cc/trees/layer_tree_host_unittest_context.cc13
-rw-r--r--cc/trees/layer_tree_host_unittest_damage.cc275
-rw-r--r--cc/trees/layer_tree_host_unittest_delegated.cc8
-rw-r--r--cc/trees/single_thread_proxy.cc39
-rw-r--r--cc/trees/single_thread_proxy.h8
-rw-r--r--cc/trees/thread_proxy.cc10
20 files changed, 644 insertions, 212 deletions
diff --git a/cc/cc_tests.gyp b/cc/cc_tests.gyp
index 7c6ee9c..3fe351a 100644
--- a/cc/cc_tests.gyp
+++ b/cc/cc_tests.gyp
@@ -34,6 +34,7 @@
'trees/layer_tree_host_unittest.cc',
'trees/layer_tree_host_unittest_animation.cc',
'trees/layer_tree_host_unittest_context.cc',
+ 'trees/layer_tree_host_unittest_damage.cc',
'trees/layer_tree_host_unittest_delegated.cc',
'trees/layer_tree_host_unittest_occlusion.cc',
'trees/layer_tree_host_unittest_scroll.cc',
diff --git a/cc/layers/delegated_renderer_layer_impl_unittest.cc b/cc/layers/delegated_renderer_layer_impl_unittest.cc
index 6e6c00f..a97d83c 100644
--- a/cc/layers/delegated_renderer_layer_impl_unittest.cc
+++ b/cc/layers/delegated_renderer_layer_impl_unittest.cc
@@ -143,7 +143,7 @@ class DelegatedRendererLayerImplTestSimple
TEST_F(DelegatedRendererLayerImplTestSimple, AddsContributingRenderPasses) {
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
// Each non-DelegatedRendererLayer added one RenderPass. The
// DelegatedRendererLayer added two contributing passes.
@@ -177,7 +177,7 @@ TEST_F(DelegatedRendererLayerImplTestSimple, AddsContributingRenderPasses) {
TEST_F(DelegatedRendererLayerImplTestSimple,
AddsQuadsToContributingRenderPasses) {
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
// Each non-DelegatedRendererLayer added one RenderPass. The
// DelegatedRendererLayer added two contributing passes.
@@ -212,7 +212,7 @@ TEST_F(DelegatedRendererLayerImplTestSimple,
TEST_F(DelegatedRendererLayerImplTestSimple, AddsQuadsToTargetRenderPass) {
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
// Each non-DelegatedRendererLayer added one RenderPass. The
// DelegatedRendererLayer added two contributing passes.
@@ -240,7 +240,7 @@ TEST_F(DelegatedRendererLayerImplTestSimple, AddsQuadsToTargetRenderPass) {
TEST_F(DelegatedRendererLayerImplTestSimple,
QuadsFromRootRenderPassAreModifiedForTheTarget) {
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
// Each non-DelegatedRendererLayer added one RenderPass. The
// DelegatedRendererLayer added two contributing passes.
@@ -273,7 +273,7 @@ TEST_F(DelegatedRendererLayerImplTestSimple,
TEST_F(DelegatedRendererLayerImplTestSimple, DoesNotOwnARenderSurface) {
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
// If the DelegatedRendererLayer is axis aligned and has opacity 1, then it
// has no need to be a RenderSurface for the quads it carries.
@@ -287,7 +287,7 @@ TEST_F(DelegatedRendererLayerImplTestSimple, DoesOwnARenderSurfaceForOpacity) {
delegated_renderer_layer_->SetOpacity(0.5f);
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
// This test case has quads from multiple layers in the delegated renderer, so
// if the DelegatedRendererLayer has opacity < 1, it should end up with a
@@ -305,7 +305,7 @@ TEST_F(DelegatedRendererLayerImplTestSimple,
delegated_renderer_layer_->SetTransform(rotation);
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
// This test case has quads from multiple layers in the delegated renderer, so
// if the DelegatedRendererLayer has opacity < 1, it should end up with a
@@ -327,7 +327,7 @@ class DelegatedRendererLayerImplTestOwnSurface
TEST_F(DelegatedRendererLayerImplTestOwnSurface, AddsRenderPasses) {
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
// Each non-DelegatedRendererLayer added one RenderPass. The
// DelegatedRendererLayer added two contributing passes and its owned surface
@@ -366,7 +366,7 @@ TEST_F(DelegatedRendererLayerImplTestOwnSurface, AddsRenderPasses) {
TEST_F(DelegatedRendererLayerImplTestOwnSurface,
AddsQuadsToContributingRenderPasses) {
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
// Each non-DelegatedRendererLayer added one RenderPass. The
// DelegatedRendererLayer added two contributing passes and its owned surface
@@ -402,7 +402,7 @@ TEST_F(DelegatedRendererLayerImplTestOwnSurface,
TEST_F(DelegatedRendererLayerImplTestOwnSurface, AddsQuadsToTargetRenderPass) {
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
// Each non-DelegatedRendererLayer added one RenderPass. The
// DelegatedRendererLayer added two contributing passes and its owned surface
@@ -428,7 +428,7 @@ TEST_F(DelegatedRendererLayerImplTestOwnSurface, AddsQuadsToTargetRenderPass) {
TEST_F(DelegatedRendererLayerImplTestOwnSurface,
QuadsFromRootRenderPassAreNotModifiedForTheTarget) {
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
// Each non-DelegatedRendererLayer added one RenderPass. The
// DelegatedRendererLayer added two contributing passes and its owned surface
@@ -639,7 +639,7 @@ TEST_F(DelegatedRendererLayerImplTestTransform, QuadsUnclipped_NoSurface) {
SetUpTest();
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
const SharedQuadState* root_delegated_shared_quad_state = NULL;
const SharedQuadState* contrib_delegated_shared_quad_state = NULL;
@@ -693,7 +693,7 @@ TEST_F(DelegatedRendererLayerImplTestTransform, QuadsClipped_NoSurface) {
SetUpTest();
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
const SharedQuadState* root_delegated_shared_quad_state = NULL;
const SharedQuadState* contrib_delegated_shared_quad_state = NULL;
@@ -754,7 +754,7 @@ TEST_F(DelegatedRendererLayerImplTestTransform, QuadsUnclipped_Surface) {
delegated_renderer_layer_->SetForceRenderSurface(true);
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
const SharedQuadState* root_delegated_shared_quad_state = NULL;
const SharedQuadState* contrib_delegated_shared_quad_state = NULL;
@@ -809,7 +809,7 @@ TEST_F(DelegatedRendererLayerImplTestTransform, QuadsClipped_Surface) {
delegated_renderer_layer_->SetForceRenderSurface(true);
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
const SharedQuadState* root_delegated_shared_quad_state = NULL;
const SharedQuadState* contrib_delegated_shared_quad_state = NULL;
@@ -1011,7 +1011,7 @@ TEST_F(DelegatedRendererLayerImplTestClip,
SetUpTest();
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
ASSERT_EQ(2u, frame.render_passes.size());
const QuadList& contrib_delegated_quad_list =
@@ -1040,7 +1040,7 @@ TEST_F(DelegatedRendererLayerImplTestClip,
SetUpTest();
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
ASSERT_EQ(2u, frame.render_passes.size());
const QuadList& contrib_delegated_quad_list =
@@ -1069,7 +1069,7 @@ TEST_F(DelegatedRendererLayerImplTestClip,
SetUpTest();
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
ASSERT_EQ(2u, frame.render_passes.size());
const QuadList& contrib_delegated_quad_list =
@@ -1099,7 +1099,7 @@ TEST_F(DelegatedRendererLayerImplTestClip,
SetUpTest();
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
ASSERT_EQ(2u, frame.render_passes.size());
const QuadList& contrib_delegated_quad_list =
@@ -1130,7 +1130,7 @@ TEST_F(DelegatedRendererLayerImplTestClip,
delegated_renderer_layer_->SetForceRenderSurface(true);
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
ASSERT_EQ(3u, frame.render_passes.size());
const QuadList& contrib_delegated_quad_list =
@@ -1159,7 +1159,7 @@ TEST_F(DelegatedRendererLayerImplTestClip,
delegated_renderer_layer_->SetForceRenderSurface(true);
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
ASSERT_EQ(3u, frame.render_passes.size());
const QuadList& contrib_delegated_quad_list =
@@ -1189,7 +1189,7 @@ TEST_F(DelegatedRendererLayerImplTestClip,
delegated_renderer_layer_->SetForceRenderSurface(true);
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
ASSERT_EQ(3u, frame.render_passes.size());
const QuadList& contrib_delegated_quad_list =
@@ -1217,7 +1217,7 @@ TEST_F(DelegatedRendererLayerImplTestClip, QuadsClipped_LayerClipped_Surface) {
delegated_renderer_layer_->SetForceRenderSurface(true);
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
ASSERT_EQ(3u, frame.render_passes.size());
const QuadList& contrib_delegated_quad_list =
diff --git a/cc/output/delegating_renderer_unittest.cc b/cc/output/delegating_renderer_unittest.cc
index 5357a58..e270860 100644
--- a/cc/output/delegating_renderer_unittest.cc
+++ b/cc/output/delegating_renderer_unittest.cc
@@ -43,8 +43,9 @@ class DelegatingRendererTestDraw : public DelegatingRendererTest {
virtual void AfterTest() OVERRIDE {}
- virtual bool PrepareToDrawOnThread(
- LayerTreeHostImpl*, LayerTreeHostImpl::FrameData* frame, bool result)
+ virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
+ LayerTreeHostImpl::FrameData* frame,
+ bool result)
OVERRIDE {
EXPECT_EQ(0u, output_surface_->num_sent_frames());
diff --git a/cc/test/fake_layer_tree_host_impl.h b/cc/test/fake_layer_tree_host_impl.h
index d46c625..5f8e0a4 100644
--- a/cc/test/fake_layer_tree_host_impl.h
+++ b/cc/test/fake_layer_tree_host_impl.h
@@ -20,7 +20,7 @@ class FakeLayerTreeHostImpl : public LayerTreeHostImpl {
void ForcePrepareToDraw() {
LayerTreeHostImpl::FrameData frame_data;
- PrepareToDraw(&frame_data);
+ PrepareToDraw(&frame_data, gfx::Rect());
DidDrawAllLayers(frame_data);
}
diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc
index d602334..f1bad56 100644
--- a/cc/test/layer_tree_test.cc
+++ b/cc/test/layer_tree_test.cc
@@ -26,10 +26,9 @@
namespace cc {
-TestHooks::TestHooks() {
- fake_client_.reset(
- new FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D));
-}
+TestHooks::TestHooks()
+ : fake_client_(
+ new FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D)) {}
TestHooks::~TestHooks() {}
@@ -100,8 +99,8 @@ class LayerTreeHostImplForTesting : public LayerTreeHostImpl {
test_hooks_->TreeActivatedOnThread(this);
}
- virtual bool PrepareToDraw(FrameData* frame) OVERRIDE {
- bool result = LayerTreeHostImpl::PrepareToDraw(frame);
+ virtual bool PrepareToDraw(FrameData* frame, gfx::Rect damage_rect) OVERRIDE {
+ bool result = LayerTreeHostImpl::PrepareToDraw(frame, damage_rect);
if (!test_hooks_->PrepareToDrawOnThread(this, frame, result))
result = false;
return result;
@@ -113,8 +112,8 @@ class LayerTreeHostImplForTesting : public LayerTreeHostImpl {
test_hooks_->DrawLayersOnThread(this);
}
- virtual bool SwapBuffers() OVERRIDE {
- bool result = LayerTreeHostImpl::SwapBuffers();
+ virtual bool SwapBuffers(const LayerTreeHostImpl::FrameData& frame) OVERRIDE {
+ bool result = LayerTreeHostImpl::SwapBuffers(frame);
test_hooks_->SwapBuffersOnThread(this, result);
return result;
}
@@ -413,7 +412,9 @@ void LayerTreeTest::DoBeginTest() {
void LayerTreeTest::SetupTree() {
if (!layer_tree_host_->root_layer()) {
scoped_refptr<Layer> root_layer = Layer::Create();
+ root_layer->SetAnchorPoint(gfx::PointF());
root_layer->SetBounds(gfx::Size(1, 1));
+ root_layer->SetIsDrawable(true);
layer_tree_host_->SetRootLayer(root_layer);
}
diff --git a/cc/test/layer_tree_test.h b/cc/test/layer_tree_test.h
index 0c56267..6be09b8 100644
--- a/cc/test/layer_tree_test.h
+++ b/cc/test/layer_tree_test.h
@@ -30,6 +30,8 @@ class TestHooks : public WebKit::WebAnimationDelegate {
TestHooks();
virtual ~TestHooks();
+ void ReadSettings(const LayerTreeSettings& settings);
+
virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) {}
virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) {}
virtual void TreeActivatedOnThread(LayerTreeHostImpl* host_impl) {}
diff --git a/cc/trees/damage_tracker.cc b/cc/trees/damage_tracker.cc
index 94ab9fa..16ae0a1 100644
--- a/cc/trees/damage_tracker.cc
+++ b/cc/trees/damage_tracker.cc
@@ -22,8 +22,7 @@ scoped_ptr<DamageTracker> DamageTracker::Create() {
DamageTracker::DamageTracker()
: current_rect_history_(new RectMap),
- next_rect_history_(new RectMap),
- force_full_damage_next_update_(false) {}
+ next_rect_history_(new RectMap) {}
DamageTracker::~DamageTracker() {}
@@ -135,10 +134,8 @@ void DamageTracker::UpdateDamageTrackingState(
gfx::RectF damage_rect_for_this_update;
- if (force_full_damage_next_update_ ||
- target_surface_property_changed_only_from_descendant) {
+ if (target_surface_property_changed_only_from_descendant) {
damage_rect_for_this_update = target_surface_content_rect;
- force_full_damage_next_update_ = false;
} else {
// TODO(shawnsingh): can we clamp this damage to the surface's content rect?
// (affects performance, but not correctness)
diff --git a/cc/trees/damage_tracker.h b/cc/trees/damage_tracker.h
index f09fe32..0627687 100644
--- a/cc/trees/damage_tracker.h
+++ b/cc/trees/damage_tracker.h
@@ -36,7 +36,7 @@ class CC_EXPORT DamageTracker {
~DamageTracker();
void DidDrawDamagedArea() { current_damage_rect_ = gfx::RectF(); }
- void ForceFullDamageNextUpdate() { force_full_damage_next_update_ = true; }
+ void AddDamageNextUpdate(gfx::RectF dmg) { current_damage_rect_.Union(dmg); }
void UpdateDamageTrackingState(
const LayerImplList& layer_list,
int target_surface_layer_id,
@@ -74,7 +74,6 @@ class CC_EXPORT DamageTracker {
scoped_ptr<RectMap> next_rect_history_;
gfx::RectF current_damage_rect_;
- bool force_full_damage_next_update_;
DISALLOW_COPY_AND_ASSIGN(DamageTracker);
};
diff --git a/cc/trees/damage_tracker_unittest.cc b/cc/trees/damage_tracker_unittest.cc
index d46a9a4..03767dc 100644
--- a/cc/trees/damage_tracker_unittest.cc
+++ b/cc/trees/damage_tracker_unittest.cc
@@ -1262,30 +1262,35 @@ TEST_F(DamageTrackerTest, VerifyDamageForReplicaMaskWithAnchor) {
EXPECT_FLOAT_RECT_EQ(gfx::RectF(206.f, 200.f, 6.f, 8.f), child_damage_rect);
}
-TEST_F(DamageTrackerTest, VerifyDamageWhenForcedFullDamage) {
+TEST_F(DamageTrackerTest, DamageWhenAddedExternally) {
scoped_ptr<LayerImpl> root = CreateAndSetUpTestTreeWithOneSurface();
LayerImpl* child = root->children()[0];
- // Case 1: This test ensures that when the tracker is forced to have full
- // damage, that it takes priority over any other partial damage.
+ // Case 1: This test ensures that when the tracker is given damage, that
+ // it is included with any other partial damage.
//
ClearDamageForAllSurfaces(root.get());
- child->set_update_rect(gfx::RectF(10.f, 11.f, 12.f, 13.f));
- root->render_surface()->damage_tracker()->ForceFullDamageNextUpdate();
+ child->set_update_rect(gfx::RectF(10, 11, 12, 13));
+ root->render_surface()->damage_tracker()->AddDamageNextUpdate(
+ gfx::RectF(15, 16, 32, 33));
EmulateDrawingOneFrame(root.get());
gfx::RectF root_damage_rect =
- root->render_surface()->damage_tracker()->current_damage_rect();
- EXPECT_FLOAT_RECT_EQ(gfx::RectF(0.f, 0.f, 500.f, 500.f), root_damage_rect);
+ root->render_surface()->damage_tracker()->current_damage_rect();
+ EXPECT_FLOAT_RECT_EQ(
+ gfx::UnionRects(gfx::RectF(15, 16, 32, 33),
+ gfx::RectF(100+10, 100+11, 12, 13)),
+ root_damage_rect);
- // Case 2: An additional sanity check that forcing full damage works even
- // when nothing on the layer tree changed.
+ // Case 2: An additional sanity check that adding damage works even when
+ // nothing on the layer tree changed.
//
ClearDamageForAllSurfaces(root.get());
- root->render_surface()->damage_tracker()->ForceFullDamageNextUpdate();
+ root->render_surface()->damage_tracker()->AddDamageNextUpdate(
+ gfx::RectF(30, 31, 14, 15));
EmulateDrawingOneFrame(root.get());
root_damage_rect =
- root->render_surface()->damage_tracker()->current_damage_rect();
- EXPECT_FLOAT_RECT_EQ(gfx::RectF(0.f, 0.f, 500.f, 500.f), root_damage_rect);
+ root->render_surface()->damage_tracker()->current_damage_rect();
+ EXPECT_FLOAT_RECT_EQ(gfx::RectF(30, 31, 14, 15), root_damage_rect);
}
TEST_F(DamageTrackerTest, VerifyDamageForEmptyLayerList) {
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index 68083c2..7152fcb 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -139,7 +139,7 @@ class LayerTreeHostImplTimeSourceAdapter : public TimeSourceClient {
};
LayerTreeHostImpl::FrameData::FrameData()
- : contains_incomplete_tile(false) {}
+ : contains_incomplete_tile(false), has_no_damage(false) {}
LayerTreeHostImpl::FrameData::~FrameData() {}
@@ -183,6 +183,7 @@ LayerTreeHostImpl::LayerTreeHostImpl(
last_sent_memory_visible_bytes_(0),
last_sent_memory_visible_and_nearby_bytes_(0),
last_sent_memory_use_bytes_(0),
+ next_frame_damages_full_device_viewport_(false),
animation_registrar_(AnimationRegistrar::Create()),
rendering_stats_instrumentation_(rendering_stats_instrumentation) {
DCHECK(proxy_->IsImplThread());
@@ -508,6 +509,23 @@ bool LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) {
TrackDamageForAllSurfaces(active_tree_->root_layer(),
*frame->render_surface_layer_list);
+ // If the root render surface has no visible damage, then don't generate a
+ // frame at all.
+ RenderSurfaceImpl* root_surface =
+ active_tree_->root_layer()->render_surface();
+ bool root_surface_has_no_visible_damage =
+ !root_surface->damage_tracker()->current_damage_rect().Intersects(
+ root_surface->content_rect());
+ bool root_surface_has_contributing_layers =
+ !root_surface->layer_list().empty();
+ if (root_surface_has_contributing_layers &&
+ root_surface_has_no_visible_damage) {
+ TRACE_EVENT0("cc",
+ "LayerTreeHostImpl::CalculateRenderPasses::EmptyDamageRect");
+ frame->has_no_damage = true;
+ return true;
+ }
+
TRACE_EVENT1("cc",
"LayerTreeHostImpl::CalculateRenderPasses",
"render_surface_layer_list.size()",
@@ -675,6 +693,8 @@ bool LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) {
RemoveRenderPasses(CullRenderPassesWithCachedTextures(renderer_.get()),
frame);
+ // If we're making a frame to draw, it better have at least one render pass.
+ DCHECK(!frame->render_passes.empty());
return draw_frame;
}
@@ -827,7 +847,8 @@ void LayerTreeHostImpl::RemoveRenderPasses(RenderPassCuller culler,
}
}
-bool LayerTreeHostImpl::PrepareToDraw(FrameData* frame) {
+bool LayerTreeHostImpl::PrepareToDraw(FrameData* frame,
+ gfx::Rect device_viewport_damage_rect) {
TRACE_EVENT0("cc", "LayerTreeHostImpl::PrepareToDraw");
active_tree_->UpdateDrawProperties(
@@ -837,6 +858,17 @@ bool LayerTreeHostImpl::PrepareToDraw(FrameData* frame) {
frame->render_passes.clear();
frame->render_passes_by_id.clear();
frame->will_draw_layers.clear();
+ frame->contains_incomplete_tile = false;
+ frame->has_no_damage = false;
+
+ if (active_tree_->root_layer()) {
+ if (next_frame_damages_full_device_viewport_)
+ device_viewport_damage_rect.Union(gfx::Rect(device_viewport_size_));
+
+ active_tree_->root_layer()->render_surface()->damage_tracker()->
+ AddDamageNextUpdate(device_viewport_damage_rect);
+ }
+ next_frame_damages_full_device_viewport_ = false;
if (!CalculateRenderPasses(frame))
return false;
@@ -997,6 +1029,10 @@ void LayerTreeHostImpl::DrawLayers(FrameData* frame,
base::TimeTicks frame_begin_time) {
TRACE_EVENT0("cc", "LayerTreeHostImpl::DrawLayers");
DCHECK(CanDraw());
+
+ if (frame->has_no_damage)
+ return;
+
DCHECK(!frame->render_passes.empty());
fps_counter_->SaveTimeStamp(frame_begin_time);
@@ -1074,7 +1110,9 @@ const RendererCapabilities& LayerTreeHostImpl::GetRendererCapabilities() const {
return renderer_->Capabilities();
}
-bool LayerTreeHostImpl::SwapBuffers() {
+bool LayerTreeHostImpl::SwapBuffers(const LayerTreeHostImpl::FrameData& frame) {
+ if (frame.has_no_damage)
+ return false;
return renderer_->SwapBuffers();
}
@@ -1763,12 +1801,7 @@ scoped_ptr<ScrollAndScaleSet> LayerTreeHostImpl::ProcessScrollDeltas() {
}
void LayerTreeHostImpl::SetFullRootLayerDamage() {
- if (active_tree_->root_layer()) {
- RenderSurfaceImpl* render_surface =
- active_tree_->root_layer()->render_surface();
- if (render_surface)
- render_surface->damage_tracker()->ForceFullDamageNextUpdate();
- }
+ next_frame_damages_full_device_viewport_ = true;
}
void LayerTreeHostImpl::AnimatePageScale(base::TimeTicks time) {
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h
index 016b165..0730c73 100644
--- a/cc/trees/layer_tree_host_impl.h
+++ b/cc/trees/layer_tree_host_impl.h
@@ -131,6 +131,7 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandlerClient,
const LayerImplList* render_surface_layer_list;
LayerImplList will_draw_layers;
bool contains_incomplete_tile;
+ bool has_no_damage;
// RenderPassSink implementation.
virtual void AppendRenderPass(scoped_ptr<RenderPass> render_pass) OVERRIDE;
@@ -150,7 +151,8 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandlerClient,
// to avoid displaying the frame. If PrepareToDraw is called, DidDrawAllLayers
// must also be called, regardless of whether DrawLayers is called between the
// two.
- virtual bool PrepareToDraw(FrameData* frame);
+ virtual bool PrepareToDraw(FrameData* frame,
+ gfx::Rect device_viewport_damage_rect);
virtual void DrawLayers(FrameData* frame, base::TimeTicks frame_begin_time);
// Must be called if and only if PrepareToDraw was called.
void DidDrawAllLayers(const FrameData& frame);
@@ -208,7 +210,7 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandlerClient,
Renderer* renderer() { return renderer_.get(); }
const RendererCapabilities& GetRendererCapabilities() const;
- virtual bool SwapBuffers();
+ virtual bool SwapBuffers(const FrameData& frame);
void EnableVSyncNotification(bool enable);
void Readback(void* pixels, gfx::Rect rect_in_device_viewport);
@@ -462,6 +464,8 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandlerClient,
size_t last_sent_memory_visible_and_nearby_bytes_;
size_t last_sent_memory_use_bytes_;
+ bool next_frame_damages_full_device_viewport_;
+
base::TimeTicks current_frame_time_;
scoped_ptr<AnimationRegistrar> animation_registrar_;
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc
index 40d0ced..49c9b0b 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -224,7 +224,7 @@ class LayerTreeHostImplTest : public testing::Test,
void InitializeRendererAndDrawFrame() {
host_impl_->InitializeRenderer(CreateOutputSurface());
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
host_impl_->DidDrawAllLayers(frame);
}
@@ -242,7 +242,7 @@ class LayerTreeHostImplTest : public testing::Test,
void DrawOneFrame() {
LayerTreeHostImpl::FrameData frame_data;
- host_impl_->PrepareToDraw(&frame_data);
+ host_impl_->PrepareToDraw(&frame_data, gfx::Rect());
host_impl_->DidDrawAllLayers(frame_data);
}
@@ -1058,7 +1058,7 @@ TEST_F(LayerTreeHostImplTest, DidDrawNotCalledOnHiddenLayer) {
EXPECT_FALSE(layer->will_draw_called());
EXPECT_FALSE(layer->did_draw_called());
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
host_impl_->DidDrawAllLayers(frame);
@@ -1073,7 +1073,7 @@ TEST_F(LayerTreeHostImplTest, DidDrawNotCalledOnHiddenLayer) {
EXPECT_FALSE(layer->will_draw_called());
EXPECT_FALSE(layer->did_draw_called());
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
host_impl_->DidDrawAllLayers(frame);
@@ -1112,7 +1112,7 @@ TEST_F(LayerTreeHostImplTest, WillDrawNotCalledOnOccludedLayer) {
EXPECT_FALSE(top_layer->will_draw_called());
EXPECT_FALSE(top_layer->did_draw_called());
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
host_impl_->DidDrawAllLayers(frame);
@@ -1144,7 +1144,7 @@ TEST_F(LayerTreeHostImplTest, DidDrawCalledOnAllLayers) {
EXPECT_FALSE(layer2->did_draw_called());
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
host_impl_->DidDrawAllLayers(frame);
@@ -1216,7 +1216,7 @@ TEST_F(LayerTreeHostImplTest, PrepareToDrawFailsWhenAnimationUsesCheckerboard) {
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
host_impl_->DidDrawAllLayers(frame);
@@ -1234,7 +1234,7 @@ TEST_F(LayerTreeHostImplTest, PrepareToDrawFailsWhenAnimationUsesCheckerboard) {
false,
host_impl_->resource_provider()));
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
host_impl_->DidDrawAllLayers(frame);
@@ -1252,7 +1252,7 @@ TEST_F(LayerTreeHostImplTest, PrepareToDrawFailsWhenAnimationUsesCheckerboard) {
true,
host_impl_->resource_provider()));
- EXPECT_FALSE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_FALSE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
host_impl_->DidDrawAllLayers(frame);
@@ -1269,7 +1269,7 @@ TEST_F(LayerTreeHostImplTest, PrepareToDrawFailsWhenAnimationUsesCheckerboard) {
true,
host_impl_->resource_provider()));
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
host_impl_->DidDrawAllLayers(frame);
}
@@ -1308,6 +1308,7 @@ TEST_F(LayerTreeHostImplTest, ScrollNonScrollableRootWithTopControls) {
root->SetContentBounds(layer_size);
root->SetPosition(gfx::PointF());
root->SetAnchorPoint(gfx::PointF());
+ root->SetDrawsContent(false);
host_impl_->active_tree()->SetRootLayer(root.Pass());
host_impl_->active_tree()->FindRootScrollLayer();
InitializeRendererAndDrawFrame();
@@ -1610,7 +1611,7 @@ TEST_F(LayerTreeHostImplTest, PageScaleDeltaAppliedToRootScrollLayerOnly) {
// Make sure all the layers are drawn with the page scale delta applied, i.e.,
// the page scale delta on the root layer is applied hierarchically.
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
host_impl_->DidDrawAllLayers(frame);
@@ -2146,7 +2147,8 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
// Opaque layer, drawn without blending.
layer1->SetContentsOpaque(true);
layer1->SetExpectation(false, false);
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
EXPECT_TRUE(layer1->quads_appended());
host_impl_->DidDrawAllLayers(frame);
@@ -2154,7 +2156,8 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
// Layer with translucent content and painting, so drawn with blending.
layer1->SetContentsOpaque(false);
layer1->SetExpectation(true, false);
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
EXPECT_TRUE(layer1->quads_appended());
host_impl_->DidDrawAllLayers(frame);
@@ -2163,7 +2166,8 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
layer1->SetContentsOpaque(true);
layer1->SetOpacity(0.5f);
layer1->SetExpectation(true, false);
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
EXPECT_TRUE(layer1->quads_appended());
host_impl_->DidDrawAllLayers(frame);
@@ -2172,7 +2176,8 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
layer1->SetContentsOpaque(true);
layer1->SetOpacity(0.5f);
layer1->SetExpectation(true, false);
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
EXPECT_TRUE(layer1->quads_appended());
host_impl_->DidDrawAllLayers(frame);
@@ -2189,10 +2194,12 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
layer1->SetContentsOpaque(true);
layer1->SetOpacity(1.f);
layer1->SetExpectation(false, false);
+ layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
layer2->SetContentsOpaque(true);
layer2->SetOpacity(1.f);
layer2->SetExpectation(false, false);
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ layer2->set_update_rect(gfx::RectF(layer1->content_bounds()));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
EXPECT_TRUE(layer1->quads_appended());
EXPECT_TRUE(layer2->quads_appended());
@@ -2202,8 +2209,10 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
// Child layer with opaque content, drawn without blending.
layer1->SetContentsOpaque(false);
layer1->SetExpectation(true, false);
+ layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
layer2->SetExpectation(false, false);
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ layer2->set_update_rect(gfx::RectF(layer1->content_bounds()));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
EXPECT_TRUE(layer1->quads_appended());
EXPECT_TRUE(layer2->quads_appended());
@@ -2214,8 +2223,10 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
// Child layer with opaque content, drawn without blending.
layer1->SetContentsOpaque(true);
layer1->SetExpectation(false, false);
+ layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
layer2->SetExpectation(false, false);
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ layer2->set_update_rect(gfx::RectF(layer1->content_bounds()));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
EXPECT_TRUE(layer1->quads_appended());
EXPECT_TRUE(layer2->quads_appended());
@@ -2229,8 +2240,10 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
layer1->SetContentsOpaque(true);
layer1->SetOpacity(0.5f);
layer1->SetExpectation(false, true);
+ layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
layer2->SetExpectation(false, false);
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ layer2->set_update_rect(gfx::RectF(layer1->content_bounds()));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
EXPECT_TRUE(layer1->quads_appended());
EXPECT_TRUE(layer2->quads_appended());
@@ -2241,10 +2254,12 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
layer1->SetContentsOpaque(true);
layer1->SetOpacity(1.f);
layer1->SetExpectation(false, false);
+ layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
layer2->SetContentsOpaque(true);
layer2->SetOpacity(0.5f);
layer2->SetExpectation(true, false);
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ layer2->set_update_rect(gfx::RectF(layer1->content_bounds()));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
EXPECT_TRUE(layer1->quads_appended());
EXPECT_TRUE(layer2->quads_appended());
@@ -2254,10 +2269,12 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
layer1->SetContentsOpaque(true);
layer1->SetOpacity(1.f);
layer1->SetExpectation(false, false);
+ layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
layer2->SetContentsOpaque(false);
layer2->SetOpacity(1.f);
layer2->SetExpectation(true, false);
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ layer2->set_update_rect(gfx::RectF(layer1->content_bounds()));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
EXPECT_TRUE(layer1->quads_appended());
EXPECT_TRUE(layer2->quads_appended());
@@ -2268,10 +2285,12 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
layer1->SetContentsOpaque(true);
layer1->SetOpacity(1.f);
layer1->SetExpectation(false, false);
+ layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
layer2->SetContentsOpaque(true);
layer2->SetOpacity(1.f);
layer2->SetExpectation(false, false);
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ layer2->set_update_rect(gfx::RectF(layer1->content_bounds()));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
EXPECT_TRUE(layer1->quads_appended());
EXPECT_TRUE(layer2->quads_appended());
@@ -2283,7 +2302,8 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
layer1->SetQuadVisibleRect(gfx::Rect(5, 5, 5, 5));
layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
layer1->SetExpectation(true, false);
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
EXPECT_TRUE(layer1->quads_appended());
host_impl_->DidDrawAllLayers(frame);
@@ -2294,7 +2314,8 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
layer1->SetQuadVisibleRect(gfx::Rect(5, 5, 5, 2));
layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
layer1->SetExpectation(true, false);
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
EXPECT_TRUE(layer1->quads_appended());
host_impl_->DidDrawAllLayers(frame);
@@ -2305,7 +2326,8 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
layer1->SetQuadVisibleRect(gfx::Rect(7, 5, 3, 5));
layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
layer1->SetExpectation(true, false);
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
EXPECT_TRUE(layer1->quads_appended());
host_impl_->DidDrawAllLayers(frame);
@@ -2317,7 +2339,8 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
layer1->SetQuadVisibleRect(gfx::Rect(5, 5, 2, 5));
layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
layer1->SetExpectation(false, false);
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ layer1->set_update_rect(gfx::RectF(layer1->content_bounds()));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
EXPECT_TRUE(layer1->quads_appended());
host_impl_->DidDrawAllLayers(frame);
@@ -2351,7 +2374,7 @@ TEST_F(LayerTreeHostImplTest, ViewportCovered) {
child->SetQuadVisibleRect(gfx::Rect(layer_rect.size()));
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
ASSERT_EQ(1u, frame.render_passes.size());
size_t num_gutter_quads = 0;
@@ -2376,7 +2399,7 @@ TEST_F(LayerTreeHostImplTest, ViewportCovered) {
child->SetQuadVisibleRect(gfx::Rect(layer_rect.size()));
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
ASSERT_EQ(1u, frame.render_passes.size());
size_t num_gutter_quads = 0;
@@ -2401,7 +2424,7 @@ TEST_F(LayerTreeHostImplTest, ViewportCovered) {
child->SetQuadVisibleRect(gfx::Rect(layer_rect.size()));
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
ASSERT_EQ(1u, frame.render_passes.size());
size_t num_gutter_quads = 0;
@@ -2457,12 +2480,13 @@ TEST_F(LayerTreeHostImplTest, ReshapeNotCalledUntilDraw) {
FakeDrawableLayerImpl::Create(host_impl_->active_tree(), 1);
root->SetAnchorPoint(gfx::PointF());
root->SetBounds(gfx::Size(10, 10));
+ root->SetContentBounds(gfx::Size(10, 10));
root->SetDrawsContent(true);
host_impl_->active_tree()->SetRootLayer(root.Pass());
EXPECT_FALSE(reshape_tracker->reshape_called());
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
EXPECT_TRUE(reshape_tracker->reshape_called());
host_impl_->DidDrawAllLayers(frame);
@@ -2531,10 +2555,10 @@ TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) {
LayerTreeHostImpl::FrameData frame;
// First frame, the entire screen should get swapped.
- EXPECT_TRUE(layer_tree_host_impl->PrepareToDraw(&frame));
+ EXPECT_TRUE(layer_tree_host_impl->PrepareToDraw(&frame, gfx::Rect()));
layer_tree_host_impl->DrawLayers(&frame, base::TimeTicks::Now());
layer_tree_host_impl->DidDrawAllLayers(frame);
- layer_tree_host_impl->SwapBuffers();
+ layer_tree_host_impl->SwapBuffers(frame);
gfx::Rect actual_swap_rect = partial_swap_tracker->partial_swap_rect();
gfx::Rect expected_swap_rect = gfx::Rect(0, 0, 500, 500);
EXPECT_EQ(expected_swap_rect.x(), actual_swap_rect.x());
@@ -2548,10 +2572,10 @@ TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) {
// expected swap rect: vertically flipped, with origin at bottom left corner.
layer_tree_host_impl->active_tree()->root_layer()->children()[0]->SetPosition(
gfx::PointF());
- EXPECT_TRUE(layer_tree_host_impl->PrepareToDraw(&frame));
+ EXPECT_TRUE(layer_tree_host_impl->PrepareToDraw(&frame, gfx::Rect()));
layer_tree_host_impl->DrawLayers(&frame, base::TimeTicks::Now());
host_impl_->DidDrawAllLayers(frame);
- layer_tree_host_impl->SwapBuffers();
+ layer_tree_host_impl->SwapBuffers(frame);
actual_swap_rect = partial_swap_tracker->partial_swap_rect();
expected_swap_rect = gfx::Rect(0, 500-28, 26, 28);
EXPECT_EQ(expected_swap_rect.x(), actual_swap_rect.x());
@@ -2565,10 +2589,10 @@ TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) {
layer_tree_host_impl->SetViewportSize(gfx::Size(10, 10), gfx::Size(10, 10));
// This will damage everything.
layer_tree_host_impl->active_tree()->root_layer()->SetOpacity(0.7f);
- EXPECT_TRUE(layer_tree_host_impl->PrepareToDraw(&frame));
+ EXPECT_TRUE(layer_tree_host_impl->PrepareToDraw(&frame, gfx::Rect()));
layer_tree_host_impl->DrawLayers(&frame, base::TimeTicks::Now());
host_impl_->DidDrawAllLayers(frame);
- layer_tree_host_impl->SwapBuffers();
+ layer_tree_host_impl->SwapBuffers(frame);
actual_swap_rect = partial_swap_tracker->partial_swap_rect();
expected_swap_rect = gfx::Rect(10, 10);
EXPECT_EQ(expected_swap_rect.x(), actual_swap_rect.x());
@@ -2597,7 +2621,7 @@ TEST_F(LayerTreeHostImplTest, RootLayerDoesntCreateExtraSurface) {
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
EXPECT_EQ(1u, frame.render_surface_layer_list->size());
EXPECT_EQ(1u, frame.render_passes.size());
host_impl_->DidDrawAllLayers(frame);
@@ -2743,7 +2767,7 @@ TEST_F(LayerTreeHostImplTest, NoPartialSwap) {
harness.MustSetNoScissor();
{
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
host_impl_->DidDrawAllLayers(frame);
}
@@ -2756,7 +2780,7 @@ TEST_F(LayerTreeHostImplTest, NoPartialSwap) {
harness.MustSetScissor(0, 0, 10, 10);
{
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
host_impl_->DidDrawAllLayers(frame);
}
@@ -2779,7 +2803,7 @@ TEST_F(LayerTreeHostImplTest, PartialSwap) {
harness.MustDrawSolidQuad();
{
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
host_impl_->DidDrawAllLayers(frame);
}
@@ -2794,7 +2818,7 @@ TEST_F(LayerTreeHostImplTest, PartialSwap) {
harness.MustDrawSolidQuad();
{
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
host_impl_->DidDrawAllLayers(frame);
}
@@ -2903,7 +2927,7 @@ TEST_F(LayerTreeHostImplTest, ContributingLayerEmptyScissorPartialSwap) {
SetupLayersForOpacity(true, this, &proxy_, &stats_instrumentation_);
{
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame));
+ EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
// Verify all quads have been computed
ASSERT_EQ(2U, frame.render_passes.size());
@@ -2924,7 +2948,7 @@ TEST_F(LayerTreeHostImplTest, ContributingLayerEmptyScissorNoPartialSwap) {
SetupLayersForOpacity(false, this, &proxy_, &stats_instrumentation_);
{
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame));
+ EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
// Verify all quads have been computed
ASSERT_EQ(2U, frame.render_passes.size());
@@ -3019,10 +3043,10 @@ TEST_F(LayerTreeHostImplTest, LayersFreeTextures) {
EXPECT_EQ(0u, context3d->NumTextures());
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
host_impl_->DidDrawAllLayers(frame);
- host_impl_->SwapBuffers();
+ host_impl_->SwapBuffers(frame);
EXPECT_GT(context3d->NumTextures(), 0u);
@@ -3062,14 +3086,15 @@ TEST_F(LayerTreeHostImplTest, HasTransparentBackground) {
EXPECT_CALL(*mock_context, drawElements(_, _, _, _))
.Times(1);
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
host_impl_->DidDrawAllLayers(frame);
Mock::VerifyAndClearExpectations(&mock_context);
// Verify no quads are drawn when transparent background is set.
host_impl_->active_tree()->set_has_transparent_background(true);
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ host_impl_->SetFullRootLayerDamage();
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
host_impl_->DidDrawAllLayers(frame);
Mock::VerifyAndClearExpectations(&mock_context);
@@ -3214,7 +3239,7 @@ TEST_F(LayerTreeHostImplTest, TextureCachingWithOcclusion) {
// Initial draw - must receive all quads
{
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame));
+ EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
// Must receive 3 render passes.
// For Root, there are 2 quads; for S1, there are 2 quads (1 is occluded);
@@ -3237,7 +3262,7 @@ TEST_F(LayerTreeHostImplTest, TextureCachingWithOcclusion) {
layer_s2_ptr->SetTransform(transform);
{
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame));
+ EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
// Must receive 2 render passes.
// For Root, there are 2 quads
@@ -3261,7 +3286,7 @@ TEST_F(LayerTreeHostImplTest, TextureCachingWithOcclusion) {
layer_s2_ptr->SetTransform(transform);
{
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame));
+ EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
// Must receive 1 render pass - for the root.
ASSERT_EQ(1U, frame.render_passes.size());
@@ -3335,7 +3360,7 @@ TEST_F(LayerTreeHostImplTest, TextureCachingWithOcclusionEarlyOut) {
// Initial draw - must receive all quads
{
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame));
+ EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
// Must receive 3 render passes.
// For Root, there are 2 quads; for S1, there are 3 quads; for S2, there is
@@ -3360,7 +3385,7 @@ TEST_F(LayerTreeHostImplTest, TextureCachingWithOcclusionEarlyOut) {
layer_s2_ptr->SetTransform(transform);
{
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame));
+ EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
// Must receive 2 render passes.
// For Root, there are 2 quads
@@ -3384,7 +3409,7 @@ TEST_F(LayerTreeHostImplTest, TextureCachingWithOcclusionEarlyOut) {
layer_s2_ptr->SetTransform(transform);
{
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame));
+ EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
// Must receive 1 render pass - for the root.
ASSERT_EQ(1U, frame.render_passes.size());
@@ -3452,7 +3477,7 @@ TEST_F(LayerTreeHostImplTest, TextureCachingWithOcclusionExternalOverInternal) {
// Initial draw - must receive all quads
{
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame));
+ EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
// Must receive 3 render passes.
// For Root, there are 2 quads; for S1, there are 3 quads; for S2, there is
@@ -3475,7 +3500,7 @@ TEST_F(LayerTreeHostImplTest, TextureCachingWithOcclusionExternalOverInternal) {
layer_s2_ptr->SetTransform(transform);
{
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame));
+ EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
// Must receive 2 render passes.
// For Root, there are 2 quads
@@ -3543,7 +3568,7 @@ TEST_F(LayerTreeHostImplTest, TextureCachingWithOcclusionExternalNotAligned) {
// Initial draw - must receive all quads
{
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame));
+ EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
// Must receive 2 render passes.
ASSERT_EQ(2U, frame.render_passes.size());
@@ -3559,7 +3584,7 @@ TEST_F(LayerTreeHostImplTest, TextureCachingWithOcclusionExternalNotAligned) {
layer_s1_ptr->SetOpacity(0.2f);
{
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame));
+ EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
// One render pass must be gone due to cached texture.
ASSERT_EQ(1U, frame.render_passes.size());
@@ -3635,7 +3660,7 @@ TEST_F(LayerTreeHostImplTest, TextureCachingWithOcclusionPartialSwap) {
// Initial draw - must receive all quads
{
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame));
+ EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
// Must receive 3 render passes.
// For Root, there are 2 quads; for S1, there are 2 quads (one is occluded);
@@ -3658,7 +3683,7 @@ TEST_F(LayerTreeHostImplTest, TextureCachingWithOcclusionPartialSwap) {
layer_s2_ptr->SetTransform(transform);
{
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame));
+ EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
// Must receive 2 render passes.
// For Root, there are 2 quads.
@@ -3681,7 +3706,7 @@ TEST_F(LayerTreeHostImplTest, TextureCachingWithOcclusionPartialSwap) {
layer_s2_ptr->SetTransform(transform);
{
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame));
+ EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
// Root render pass only.
ASSERT_EQ(1U, frame.render_passes.size());
@@ -3775,7 +3800,8 @@ TEST_F(LayerTreeHostImplTest, TextureCachingWithScissor) {
child_pass_id));
{
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame));
+ host_impl_->SetFullRootLayerDamage();
+ EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
my_host_impl->DrawLayers(&frame, base::TimeTicks::Now());
my_host_impl->DidDrawAllLayers(frame);
}
@@ -3785,7 +3811,8 @@ TEST_F(LayerTreeHostImplTest, TextureCachingWithScissor) {
child_pass_id));
{
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame));
+ host_impl_->SetFullRootLayerDamage();
+ EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
my_host_impl->DrawLayers(&frame, base::TimeTicks::Now());
my_host_impl->DidDrawAllLayers(frame);
}
@@ -3799,7 +3826,8 @@ TEST_F(LayerTreeHostImplTest, TextureCachingWithScissor) {
child_ptr->set_update_rect(gfx::Rect(10, 10, 10, 10));
{
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame));
+ host_impl_->SetFullRootLayerDamage();
+ EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
my_host_impl->DrawLayers(&frame, base::TimeTicks::Now());
my_host_impl->DidDrawAllLayers(frame);
}
@@ -3834,7 +3862,7 @@ TEST_F(LayerTreeHostImplTest, SurfaceTextureCaching) {
gfx::Size(100, 100));
{
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame));
+ EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
// Must receive two render passes, each with one quad
ASSERT_EQ(2U, frame.render_passes.size());
@@ -3856,7 +3884,8 @@ TEST_F(LayerTreeHostImplTest, SurfaceTextureCaching) {
// Draw without any change
{
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame));
+ my_host_impl->SetFullRootLayerDamage();
+ EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
// Must receive one render pass, as the other one should be culled
ASSERT_EQ(1U, frame.render_passes.size());
@@ -3877,7 +3906,7 @@ TEST_F(LayerTreeHostImplTest, SurfaceTextureCaching) {
surface_layer_ptr->SetOpacity(0.6f);
{
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame));
+ EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
// Must receive one render pass, as the other one should be culled
ASSERT_EQ(1U, frame.render_passes.size());
@@ -3898,7 +3927,7 @@ TEST_F(LayerTreeHostImplTest, SurfaceTextureCaching) {
surface_layer_ptr->SetStackingOrderChanged(true);
{
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame));
+ EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
// Must receive two render passes, each with one quad
ASSERT_EQ(2U, frame.render_passes.size());
@@ -3928,7 +3957,7 @@ TEST_F(LayerTreeHostImplTest, SurfaceTextureCaching) {
surface_layer_ptr->SetOpacity(0.6f);
{
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame));
+ EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
// Must receive two render passes
ASSERT_EQ(2U, frame.render_passes.size());
@@ -3957,7 +3986,8 @@ TEST_F(LayerTreeHostImplTest, SurfaceTextureCaching) {
// Draw without any change, to make sure the state is clear
{
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame));
+ my_host_impl->SetFullRootLayerDamage();
+ EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
// Must receive one render pass, as the other one should be culled
ASSERT_EQ(1U, frame.render_passes.size());
@@ -3980,7 +4010,7 @@ TEST_F(LayerTreeHostImplTest, SurfaceTextureCaching) {
intermediate_layer_ptr->SetTransform(transform);
{
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame));
+ EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
// Must receive one render pass, as the other one should be culled.
ASSERT_EQ(1U, frame.render_passes.size());
@@ -4021,7 +4051,7 @@ TEST_F(LayerTreeHostImplTest, SurfaceTextureCachingNoPartialSwap) {
gfx::Size(100, 100));
{
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame));
+ EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
// Must receive two render passes, each with one quad
ASSERT_EQ(2U, frame.render_passes.size());
@@ -4050,7 +4080,8 @@ TEST_F(LayerTreeHostImplTest, SurfaceTextureCachingNoPartialSwap) {
// Draw without any change
{
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame));
+ my_host_impl->SetFullRootLayerDamage();
+ EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
// Even though there was no change, we set the damage to entire viewport.
// One of the passes should be culled as a result, since contents didn't
@@ -4058,8 +4089,6 @@ TEST_F(LayerTreeHostImplTest, SurfaceTextureCachingNoPartialSwap) {
ASSERT_EQ(1U, frame.render_passes.size());
EXPECT_EQ(1U, frame.render_passes[0]->quad_list.size());
- EXPECT_TRUE(frame.render_passes[0]->damage_rect.IsEmpty());
-
my_host_impl->DrawLayers(&frame, base::TimeTicks::Now());
my_host_impl->DidDrawAllLayers(frame);
}
@@ -4068,7 +4097,7 @@ TEST_F(LayerTreeHostImplTest, SurfaceTextureCachingNoPartialSwap) {
surface_layer_ptr->SetOpacity(0.6f);
{
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame));
+ EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
// Must receive one render pass, as the other one should be culled
ASSERT_EQ(1U, frame.render_passes.size());
@@ -4089,7 +4118,7 @@ TEST_F(LayerTreeHostImplTest, SurfaceTextureCachingNoPartialSwap) {
surface_layer_ptr->SetStackingOrderChanged(true);
{
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame));
+ EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
// Must receive two render passes, each with one quad
ASSERT_EQ(2U, frame.render_passes.size());
@@ -4119,7 +4148,7 @@ TEST_F(LayerTreeHostImplTest, SurfaceTextureCachingNoPartialSwap) {
surface_layer_ptr->SetOpacity(0.6f);
{
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame));
+ EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
// Must receive two render passes
ASSERT_EQ(2U, frame.render_passes.size());
@@ -4148,7 +4177,8 @@ TEST_F(LayerTreeHostImplTest, SurfaceTextureCachingNoPartialSwap) {
// Draw without any change, to make sure the state is clear
{
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame));
+ my_host_impl->SetFullRootLayerDamage();
+ EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
// Even though there was no change, we set the damage to entire viewport.
// One of the passes should be culled as a result, since contents didn't
@@ -4166,7 +4196,7 @@ TEST_F(LayerTreeHostImplTest, SurfaceTextureCachingNoPartialSwap) {
intermediate_layer_ptr->SetTransform(transform);
{
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame));
+ EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect()));
// Must receive one render pass, as the other one should be culled.
ASSERT_EQ(1U, frame.render_passes.size());
@@ -4645,23 +4675,39 @@ class LayerTreeHostImplTestWithDelegatingRenderer
}
void DrawFrameAndTestDamage(const gfx::RectF& expected_damage) {
- LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
- ASSERT_EQ(1u, frame.render_passes.size());
-
- // Verify the damage rect for the root render pass.
- const RenderPass* root_render_pass = frame.render_passes.back();
- EXPECT_RECT_EQ(expected_damage, root_render_pass->damage_rect);
+ bool expect_to_draw = !expected_damage.IsEmpty();
- // Verify the root layer's quad is generated and not being culled.
- ASSERT_EQ(1u, root_render_pass->quad_list.size());
- gfx::Rect expected_visible_rect(
- host_impl_->active_tree()->root_layer()->content_bounds());
- EXPECT_RECT_EQ(expected_visible_rect,
- root_render_pass->quad_list[0]->visible_rect);
+ LayerTreeHostImpl::FrameData frame;
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
+
+ if (!expect_to_draw) {
+ // With no damage, we don't draw, and no quads are created.
+ ASSERT_EQ(0u, frame.render_passes.size());
+ } else {
+ ASSERT_EQ(1u, frame.render_passes.size());
+
+ // Verify the damage rect for the root render pass.
+ const RenderPass* root_render_pass = frame.render_passes.back();
+ EXPECT_RECT_EQ(expected_damage, root_render_pass->damage_rect);
+
+ // Verify the root and child layers' quads are generated and not being
+ // culled.
+ ASSERT_EQ(2u, root_render_pass->quad_list.size());
+
+ LayerImpl* child = host_impl_->active_tree()->root_layer()->children()[0];
+ gfx::RectF expected_child_visible_rect(child->content_bounds());
+ EXPECT_RECT_EQ(expected_child_visible_rect,
+ root_render_pass->quad_list[0]->visible_rect);
+
+ LayerImpl* root = host_impl_->active_tree()->root_layer();
+ gfx::RectF expected_root_visible_rect(root->content_bounds());
+ EXPECT_RECT_EQ(expected_root_visible_rect,
+ root_render_pass->quad_list[1]->visible_rect);
+ }
host_impl_->DrawLayers(&frame, base::TimeTicks::Now());
host_impl_->DidDrawAllLayers(frame);
+ EXPECT_EQ(expect_to_draw, host_impl_->SwapBuffers(frame));
}
};
@@ -4673,14 +4719,30 @@ TEST_F(LayerTreeHostImplTestWithDelegatingRenderer, FrameIncludesDamageRect) {
root->SetBounds(gfx::Size(10, 10));
root->SetContentBounds(gfx::Size(10, 10));
root->SetDrawsContent(true);
+
+ // Child layer is in the bottom right corner.
+ scoped_ptr<SolidColorLayerImpl> child =
+ SolidColorLayerImpl::Create(host_impl_->active_tree(), 2);
+ child->SetAnchorPoint(gfx::PointF(0.f, 0.f));
+ child->SetPosition(gfx::PointF(9.f, 9.f));
+ child->SetBounds(gfx::Size(1, 1));
+ child->SetContentBounds(gfx::Size(1, 1));
+ child->SetDrawsContent(true);
+ root->AddChild(child.PassAs<LayerImpl>());
+
host_impl_->active_tree()->SetRootLayer(root.PassAs<LayerImpl>());
// Draw a frame. In the first frame, the entire viewport should be damaged.
gfx::Rect full_frame_damage = gfx::Rect(host_impl_->device_viewport_size());
DrawFrameAndTestDamage(full_frame_damage);
- // The second frame should have no damage, but the quads should still be
- // generated.
+ // The second frame has damage that doesn't touch the child layer. Its quads
+ // should still be generated.
+ gfx::Rect small_damage = gfx::Rect(0, 0, 1, 1);
+ host_impl_->active_tree()->root_layer()->set_update_rect(small_damage);
+ DrawFrameAndTestDamage(small_damage);
+
+ // The third frame should have no damage, so no quads should be generated.
gfx::Rect no_damage;
DrawFrameAndTestDamage(no_damage);
}
@@ -4763,7 +4825,7 @@ TEST_F(LayerTreeHostImplTest, MaskLayerWithScaling) {
host_impl_->SetDeviceScaleFactor(device_scale_factor);
{
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
ASSERT_EQ(1u, frame.render_passes.size());
ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size());
@@ -4791,7 +4853,7 @@ TEST_F(LayerTreeHostImplTest, MaskLayerWithScaling) {
host_impl_->active_tree()->set_needs_update_draw_properties();
{
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
ASSERT_EQ(1u, frame.render_passes.size());
ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size());
@@ -4821,7 +4883,7 @@ TEST_F(LayerTreeHostImplTest, MaskLayerWithScaling) {
host_impl_->active_tree()->set_needs_update_draw_properties();
{
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
ASSERT_EQ(1u, frame.render_passes.size());
ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size());
@@ -4885,7 +4947,7 @@ TEST_F(LayerTreeHostImplTest, MaskLayerWithDifferentBounds) {
host_impl_->SetDeviceScaleFactor(device_scale_factor);
{
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
ASSERT_EQ(1u, frame.render_passes.size());
ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size());
@@ -4913,7 +4975,7 @@ TEST_F(LayerTreeHostImplTest, MaskLayerWithDifferentBounds) {
host_impl_->active_tree()->set_needs_update_draw_properties();
{
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
ASSERT_EQ(1u, frame.render_passes.size());
ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size());
@@ -4944,7 +5006,7 @@ TEST_F(LayerTreeHostImplTest, MaskLayerWithDifferentBounds) {
host_impl_->active_tree()->set_needs_update_draw_properties();
{
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
ASSERT_EQ(1u, frame.render_passes.size());
ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size());
@@ -4968,7 +5030,7 @@ TEST_F(LayerTreeHostImplTest, MaskLayerWithDifferentBounds) {
host_impl_->active_tree()->set_needs_update_draw_properties();
{
LayerTreeHostImpl::FrameData frame;
- EXPECT_TRUE(host_impl_->PrepareToDraw(&frame));
+ EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect()));
ASSERT_EQ(1u, frame.render_passes.size());
ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size());
diff --git a/cc/trees/layer_tree_host_perftest.cc b/cc/trees/layer_tree_host_perftest.cc
index bd3849e..8f247e8 100644
--- a/cc/trees/layer_tree_host_perftest.cc
+++ b/cc/trees/layer_tree_host_perftest.cc
@@ -26,7 +26,8 @@ static const int kTimeCheckInterval = 10;
class LayerTreeHostPerfTest : public LayerTreeTest {
public:
LayerTreeHostPerfTest()
- : num_draws_(0) {
+ : num_draws_(0),
+ full_damage_each_frame_(false) {
fake_content_layer_client_.set_paint_all_opaque(true);
}
@@ -49,6 +50,8 @@ class LayerTreeHostPerfTest : public LayerTreeTest {
}
}
impl->setNeedsRedraw();
+ if (full_damage_each_frame_)
+ impl->SetFullRootLayerDamage();
}
virtual void BuildTree() {}
@@ -66,6 +69,7 @@ class LayerTreeHostPerfTest : public LayerTreeTest {
std::string test_name_;
base::TimeDelta elapsed_;
FakeContentLayerClient fake_content_layer_client_;
+ bool full_damage_each_frame_;
};
@@ -102,6 +106,14 @@ TEST_F(LayerTreeHostPerfTestJsonReader, TenTenSingleThread) {
RunTest(false);
}
+// Simulates a tab switcher scene with two stacks of 10 tabs each.
+TEST_F(LayerTreeHostPerfTestJsonReader,
+ TenTenSingleThread_FullDamageEachFrame) {
+ full_damage_each_frame_ = true;
+ ReadTestFile("10_10_layer_tree");
+ RunTest(false);
+}
+
// Simulates main-thread scrolling on each frame.
class ScrollingLayerTreePerfTest : public LayerTreeHostPerfTestJsonReader {
public:
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc
index 130e8b6..f53a618 100644
--- a/cc/trees/layer_tree_host_unittest.cc
+++ b/cc/trees/layer_tree_host_unittest.cc
@@ -120,19 +120,20 @@ class LayerTreeHostTestSetNeedsCommit2 : public LayerTreeHostTest {
virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
+ ++num_draws_;
+ }
+
+ 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();
}
- virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
- num_commits_++;
- }
-
virtual void AfterTest() OVERRIDE {
EXPECT_EQ(2, num_commits_);
- EXPECT_GE(2, num_draws_);
+ EXPECT_LE(1, num_draws_);
}
private:
@@ -694,7 +695,7 @@ class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers
// Compute all the layer transforms for the frame.
LayerTreeHostImpl::FrameData frame_data;
- impl->PrepareToDraw(&frame_data);
+ impl->PrepareToDraw(&frame_data, gfx::Rect());
impl->DidDrawAllLayers(frame_data);
const LayerImplList& render_surface_layer_list =
@@ -1124,15 +1125,15 @@ class LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit
: public LayerTreeHostTest {
public:
LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit()
- : root_layer_(ContentLayerWithUpdateTracking::Create(&fake_delegate_)),
+ : root_layer_(FakeContentLayer::Create(&client_)),
surface_layer1_(
- ContentLayerWithUpdateTracking::Create(&fake_delegate_)),
+ FakeContentLayer::Create(&client_)),
replica_layer1_(
- ContentLayerWithUpdateTracking::Create(&fake_delegate_)),
+ FakeContentLayer::Create(&client_)),
surface_layer2_(
- ContentLayerWithUpdateTracking::Create(&fake_delegate_)),
+ FakeContentLayer::Create(&client_)),
replica_layer2_(
- ContentLayerWithUpdateTracking::Create(&fake_delegate_)) {}
+ FakeContentLayer::Create(&client_)) {}
virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
settings->cache_render_pass_contents = true;
@@ -1192,19 +1193,24 @@ class LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit
}
}
+ virtual void DidCommitAndDrawFrame() OVERRIDE {
+ if (!TestEnded())
+ root_layer_->SetNeedsDisplay();
+ }
+
virtual void AfterTest() OVERRIDE {
- EXPECT_EQ(2, root_layer_->PaintContentsCount());
- EXPECT_EQ(2, surface_layer1_->PaintContentsCount());
- EXPECT_EQ(2, surface_layer2_->PaintContentsCount());
+ EXPECT_EQ(3u, root_layer_->update_count());
+ EXPECT_EQ(3u, surface_layer1_->update_count());
+ EXPECT_EQ(3u, surface_layer2_->update_count());
}
private:
- FakeContentLayerClient fake_delegate_;
- scoped_refptr<ContentLayerWithUpdateTracking> root_layer_;
- scoped_refptr<ContentLayerWithUpdateTracking> surface_layer1_;
- scoped_refptr<ContentLayerWithUpdateTracking> replica_layer1_;
- scoped_refptr<ContentLayerWithUpdateTracking> surface_layer2_;
- scoped_refptr<ContentLayerWithUpdateTracking> replica_layer2_;
+ FakeContentLayerClient client_;
+ scoped_refptr<FakeContentLayer> root_layer_;
+ scoped_refptr<FakeContentLayer> surface_layer1_;
+ scoped_refptr<FakeContentLayer> replica_layer1_;
+ scoped_refptr<FakeContentLayer> surface_layer2_;
+ scoped_refptr<FakeContentLayer> replica_layer2_;
};
SINGLE_AND_MULTI_THREAD_TEST_F(
@@ -1362,7 +1368,7 @@ class LayerTreeHostTestEvictTextures : public LayerTreeHostTest {
// the beginFrame/commit pair.
// Commits 5+6 test the path where an eviction happens during the eviction
// recovery path.
- virtual void DidCommitAndDrawFrame() OVERRIDE {
+ virtual void DidCommit() OVERRIDE {
switch (num_commits_) {
case 1:
EXPECT_TRUE(layer_->HaveBackingTexture());
@@ -1449,7 +1455,7 @@ class LayerTreeHostTestContinuousCommit : public LayerTreeHostTest {
virtual void DidCommit() OVERRIDE {
if (num_draw_layers_ == 2)
return;
- PostSetNeedsCommitToMainThread();
+ layer_tree_host()->root_layer()->SetNeedsDisplay();
}
virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
@@ -1484,7 +1490,7 @@ class LayerTreeHostTestContinuousInvalidate : public LayerTreeHostTest {
layer_tree_host()->SetViewportSize(gfx::Size(10, 10), gfx::Size(10, 10));
layer_tree_host()->root_layer()->SetBounds(gfx::Size(10, 10));
- content_layer_ = ContentLayer::Create(&fake_delegate_);
+ content_layer_ = ContentLayer::Create(&client_);
content_layer_->SetBounds(gfx::Size(10, 10));
content_layer_->SetPosition(gfx::PointF(0.f, 0.f));
content_layer_->SetAnchorPoint(gfx::PointF(0.f, 0.f));
@@ -1517,7 +1523,7 @@ class LayerTreeHostTestContinuousInvalidate : public LayerTreeHostTest {
}
private:
- FakeContentLayerClient fake_delegate_;
+ FakeContentLayerClient client_;
scoped_refptr<Layer> content_layer_;
int num_commit_complete_;
int num_draw_layers_;
diff --git a/cc/trees/layer_tree_host_unittest_context.cc b/cc/trees/layer_tree_host_unittest_context.cc
index 6b95121..abde0a8 100644
--- a/cc/trees/layer_tree_host_unittest_context.cc
+++ b/cc/trees/layer_tree_host_unittest_context.cc
@@ -155,7 +155,8 @@ class LayerTreeHostContextTest : public LayerTreeTest {
LayerTreeHostImpl::FrameData* frame,
bool result)
OVERRIDE {
- EXPECT_TRUE(result);
+ bool expect_success = !frame->has_no_damage;
+ EXPECT_EQ(expect_success, result);
if (!times_to_lose_during_draw_)
return result;
@@ -269,7 +270,8 @@ class LayerTreeHostContextTestLostContextSucceeds
}
virtual void InvalidateAndSetNeedsCommit() {
- layer_tree_host()->SetNeedsCommit();
+ // Cause damage so we try to draw.
+ layer_tree_host()->root_layer()->SetNeedsDisplay();
}
bool NextTestCase() {
@@ -1050,10 +1052,9 @@ class LayerTreeHostContextTestDontUseLostResources
}
}
- virtual bool PrepareToDrawOnThread(
- LayerTreeHostImpl* host_impl,
- LayerTreeHostImpl::FrameData* frame,
- bool result) OVERRIDE {
+ virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
+ LayerTreeHostImpl::FrameData* frame,
+ bool result) OVERRIDE {
if (host_impl->active_tree()->source_frame_number() == 2) {
// Lose the context during draw on the second commit. This will cause
// a third commit to recover.
diff --git a/cc/trees/layer_tree_host_unittest_damage.cc b/cc/trees/layer_tree_host_unittest_damage.cc
new file mode 100644
index 0000000..a66b798a
--- /dev/null
+++ b/cc/trees/layer_tree_host_unittest_damage.cc
@@ -0,0 +1,275 @@
+// Copyright 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/trees/layer_tree_host.h"
+
+#include "cc/test/fake_content_layer.h"
+#include "cc/test/fake_content_layer_client.h"
+#include "cc/test/layer_tree_test.h"
+#include "cc/trees/damage_tracker.h"
+#include "cc/trees/layer_tree_impl.h"
+
+namespace cc {
+namespace {
+
+// These tests deal with damage tracking.
+class LayerTreeHostDamageTest : public LayerTreeTest {};
+
+class LayerTreeHostDamageTestNoDamageDoesNotSwap
+ : public LayerTreeHostDamageTest {
+ virtual void BeginTest() OVERRIDE {
+ expect_swap_and_succeed_ = 0;
+ did_swaps_ = 0;
+ did_swap_and_succeed_ = 0;
+ PostSetNeedsCommitToMainThread();
+ }
+
+ virtual void SetupTree() OVERRIDE {
+ scoped_refptr<FakeContentLayer> root = FakeContentLayer::Create(&client_);
+ root->SetBounds(gfx::Size(10, 10));
+
+ // Most of the layer isn't visible.
+ content_ = FakeContentLayer::Create(&client_);
+ content_->SetBounds(gfx::Size(100, 100));
+ root->AddChild(content_);
+
+ layer_tree_host()->SetRootLayer(root);
+ LayerTreeHostDamageTest::SetupTree();
+ }
+
+ virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
+ LayerTreeHostImpl::FrameData* frame_data,
+ bool result) OVERRIDE {
+ EXPECT_TRUE(result);
+
+ int source_frame = host_impl->active_tree()->source_frame_number();
+ switch (source_frame) {
+ case 0:
+ // The first frame has damage, so we should draw and swap.
+ ++expect_swap_and_succeed_;
+ break;
+ case 1:
+ // The second frame has no damage, so we should not draw and swap.
+ break;
+ case 2:
+ // The third frame has damage again, so we should draw and swap.
+ ++expect_swap_and_succeed_;
+ break;
+ case 3:
+ // The fourth frame has no visible damage, so we should not draw and
+ // swap.
+ EndTest();
+ break;
+ }
+ return result;
+ }
+
+ virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
+ bool result) OVERRIDE {
+ ++did_swaps_;
+ if (result)
+ ++did_swap_and_succeed_;
+ EXPECT_EQ(expect_swap_and_succeed_, did_swap_and_succeed_);
+ }
+
+ virtual void DidCommit() OVERRIDE {
+ int next_frame = layer_tree_host()->commit_number();
+ switch (next_frame) {
+ case 1:
+ layer_tree_host()->SetNeedsCommit();
+ break;
+ case 2:
+ // Cause visible damage.
+ content_->SetNeedsDisplayRect(
+ gfx::Rect(layer_tree_host()->layout_viewport_size()));
+ break;
+ case 3:
+ // Cause non-visible damage.
+ content_->SetNeedsDisplayRect(gfx::Rect(90, 90, 10, 10));
+ break;
+ }
+ }
+
+ virtual void AfterTest() OVERRIDE {
+ EXPECT_EQ(4, did_swaps_);
+ EXPECT_EQ(2, expect_swap_and_succeed_);
+ EXPECT_EQ(expect_swap_and_succeed_, did_swap_and_succeed_);
+ }
+
+ FakeContentLayerClient client_;
+ scoped_refptr<FakeContentLayer> content_;
+ int expect_swap_and_succeed_;
+ int did_swaps_;
+ int did_swap_and_succeed_;
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDamageTestNoDamageDoesNotSwap);
+
+class LayerTreeHostDamageTestNoDamageReadbackDoesDraw
+ : public LayerTreeHostDamageTest {
+ virtual void BeginTest() OVERRIDE {
+ PostSetNeedsCommitToMainThread();
+ }
+
+ virtual void SetupTree() OVERRIDE {
+ scoped_refptr<FakeContentLayer> root = FakeContentLayer::Create(&client_);
+ root->SetBounds(gfx::Size(10, 10));
+
+ // Most of the layer isn't visible.
+ content_ = FakeContentLayer::Create(&client_);
+ content_->SetBounds(gfx::Size(100, 100));
+ root->AddChild(content_);
+
+ layer_tree_host()->SetRootLayer(root);
+ LayerTreeHostDamageTest::SetupTree();
+ }
+
+ virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
+ LayerTreeHostImpl::FrameData* frame_data,
+ bool result) OVERRIDE {
+ EXPECT_TRUE(result);
+
+ int source_frame = host_impl->active_tree()->source_frame_number();
+ switch (source_frame) {
+ case 0:
+ // The first frame draws and clears any damage.
+ break;
+ case 1: {
+ // The second frame is a readback, we should have damage in the readback
+ // rect, but not swap.
+ RenderSurfaceImpl* root_surface =
+ host_impl->active_tree()->root_layer()->render_surface();
+ gfx::RectF root_damage =
+ root_surface->damage_tracker()->current_damage_rect();
+ root_damage.Intersect(root_surface->content_rect());
+ EXPECT_TRUE(root_damage.Contains(gfx::Rect(3, 3, 1, 1)));
+ break;
+ }
+ case 2:
+ NOTREACHED();
+ break;
+ }
+ return result;
+ }
+
+ virtual void DidCommitAndDrawFrame() OVERRIDE {
+ int next_frame = layer_tree_host()->commit_number();
+ switch (next_frame) {
+ case 1: {
+ char pixels[4];
+ layer_tree_host()->CompositeAndReadback(static_cast<void*>(&pixels),
+ gfx::Rect(3, 3, 1, 1));
+ EndTest();
+ break;
+ }
+ }
+ }
+
+ virtual void AfterTest() OVERRIDE {}
+
+ FakeContentLayerClient client_;
+ scoped_refptr<FakeContentLayer> content_;
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDamageTestNoDamageReadbackDoesDraw);
+
+class LayerTreeHostDamageTestForcedFullDamage : public LayerTreeHostDamageTest {
+ virtual void BeginTest() OVERRIDE {
+ PostSetNeedsCommitToMainThread();
+ }
+
+ virtual void SetupTree() OVERRIDE {
+ root_ = FakeContentLayer::Create(&client_);
+ child_ = FakeContentLayer::Create(&client_);
+
+ root_->SetBounds(gfx::Size(500, 500));
+ child_->SetPosition(gfx::Point(100, 100));
+ child_->SetBounds(gfx::Size(30, 30));
+
+ root_->AddChild(child_);
+ layer_tree_host()->SetRootLayer(root_);
+ LayerTreeHostDamageTest::SetupTree();
+ }
+
+ virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
+ LayerTreeHostImpl::FrameData* frame_data,
+ bool result) OVERRIDE {
+ EXPECT_TRUE(result);
+
+ RenderSurfaceImpl* root_surface =
+ host_impl->active_tree()->root_layer()->render_surface();
+ gfx::RectF root_damage =
+ root_surface->damage_tracker()->current_damage_rect();
+ root_damage.Intersect(root_surface->content_rect());
+
+ int source_frame = host_impl->active_tree()->source_frame_number();
+ switch (source_frame) {
+ case 0:
+ // The first frame draws and clears any damage.
+ EXPECT_EQ(gfx::RectF(root_surface->content_rect()).ToString(),
+ root_damage.ToString());
+ EXPECT_FALSE(frame_data->has_no_damage);
+ break;
+ case 1:
+ // If we get a frame without damage then we don't draw.
+ EXPECT_EQ(gfx::RectF().ToString(), root_damage.ToString());
+ EXPECT_TRUE(frame_data->has_no_damage);
+
+ // Then we set full damage for the next frame.
+ host_impl->SetFullRootLayerDamage();
+ break;
+ case 2:
+ // The whole frame should be damaged as requested.
+ EXPECT_EQ(gfx::RectF(root_surface->content_rect()).ToString(),
+ root_damage.ToString());
+ EXPECT_FALSE(frame_data->has_no_damage);
+
+ // Just a part of the next frame should be damaged.
+ child_damage_rect_ = gfx::RectF(10, 11, 12, 13);
+ break;
+ case 3:
+ // The update rect in the child should be damaged.
+ EXPECT_EQ(gfx::RectF(100+10, 100+11, 12, 13).ToString(),
+ root_damage.ToString());
+ EXPECT_FALSE(frame_data->has_no_damage);
+
+ // If we damage part of the frame, but also damage the full
+ // frame, then the whole frame should be damaged.
+ child_damage_rect_ = gfx::RectF(10, 11, 12, 13);
+ host_impl->SetFullRootLayerDamage();
+ break;
+ case 4:
+ // The whole frame is damaged.
+ EXPECT_EQ(gfx::RectF(root_surface->content_rect()).ToString(),
+ root_damage.ToString());
+ EXPECT_FALSE(frame_data->has_no_damage);
+
+ EndTest();
+ break;
+ }
+ return result;
+ }
+
+ virtual void DidCommitAndDrawFrame() OVERRIDE {
+ if (!TestEnded())
+ layer_tree_host()->SetNeedsCommit();
+
+ if (!child_damage_rect_.IsEmpty()) {
+ child_->SetNeedsDisplayRect(child_damage_rect_);
+ child_damage_rect_ = gfx::RectF();
+ }
+ }
+
+ virtual void AfterTest() OVERRIDE {}
+
+ FakeContentLayerClient client_;
+ scoped_refptr<FakeContentLayer> root_;
+ scoped_refptr<FakeContentLayer> child_;
+ gfx::RectF child_damage_rect_;
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDamageTestForcedFullDamage);
+
+} // namespace
+} // namespace cc
diff --git a/cc/trees/layer_tree_host_unittest_delegated.cc b/cc/trees/layer_tree_host_unittest_delegated.cc
index cc81707..380113a 100644
--- a/cc/trees/layer_tree_host_unittest_delegated.cc
+++ b/cc/trees/layer_tree_host_unittest_delegated.cc
@@ -252,7 +252,13 @@ class LayerTreeHostDelegatedTestLayerUsesFrameDamage
if (!first_draw_for_source_frame_)
return result;
- gfx::RectF damage_rect = frame->render_passes.back()->damage_rect;
+ gfx::RectF damage_rect;
+ if (!frame->has_no_damage) {
+ damage_rect = frame->render_passes.back()->damage_rect;
+ } else {
+ // If there is no damage, then we have no render passes to send.
+ EXPECT_TRUE(frame->render_passes.empty());
+ }
switch (host_impl->active_tree()->source_frame_number()) {
case 0:
diff --git a/cc/trees/single_thread_proxy.cc b/cc/trees/single_thread_proxy.cc
index 07056c4..31a7054 100644
--- a/cc/trees/single_thread_proxy.cc
+++ b/cc/trees/single_thread_proxy.cc
@@ -54,7 +54,12 @@ bool SingleThreadProxy::CompositeAndReadback(void* pixels, gfx::Rect rect) {
TRACE_EVENT0("cc", "SingleThreadProxy::CompositeAndReadback");
DCHECK(Proxy::IsMainThread());
- if (!CommitAndComposite(base::TimeTicks::Now()))
+ gfx::Rect device_viewport_damage_rect = rect;
+
+ LayerTreeHostImpl::FrameData frame;
+ if (!CommitAndComposite(base::TimeTicks::Now(),
+ device_viewport_damage_rect,
+ &frame))
return false;
{
@@ -64,7 +69,7 @@ bool SingleThreadProxy::CompositeAndReadback(void* pixels, gfx::Rect rect) {
if (layer_tree_host_impl_->IsContextLost())
return false;
- layer_tree_host_impl_->SwapBuffers();
+ layer_tree_host_impl_->SwapBuffers(frame);
}
DidSwapFrame();
@@ -330,8 +335,13 @@ void SingleThreadProxy::DidLoseOutputSurfaceOnImplThread() {
// Called by the legacy scheduling path (e.g. where render_widget does the
// scheduling)
void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time) {
- if (CommitAndComposite(frame_begin_time)) {
- layer_tree_host_impl_->SwapBuffers();
+ gfx::Rect device_viewport_damage_rect;
+
+ LayerTreeHostImpl::FrameData frame;
+ if (CommitAndComposite(frame_begin_time,
+ device_viewport_damage_rect,
+ &frame)) {
+ layer_tree_host_impl_->SwapBuffers(frame);
DidSwapFrame();
}
}
@@ -360,7 +370,10 @@ void SingleThreadProxy::ForceSerializeOnSwapBuffers() {
void SingleThreadProxy::OnSwapBuffersCompleteOnImplThread() { NOTREACHED(); }
-bool SingleThreadProxy::CommitAndComposite(base::TimeTicks frame_begin_time) {
+bool SingleThreadProxy::CommitAndComposite(
+ base::TimeTicks frame_begin_time,
+ gfx::Rect device_viewport_damage_rect,
+ LayerTreeHostImpl::FrameData* frame) {
DCHECK(Proxy::IsMainThread());
if (!layer_tree_host_->InitializeRendererIfNeeded())
@@ -384,7 +397,10 @@ bool SingleThreadProxy::CommitAndComposite(base::TimeTicks frame_begin_time) {
layer_tree_host_->WillCommit();
DoCommit(queue.Pass());
- bool result = DoComposite(offscreen_context_provider, frame_begin_time);
+ bool result = DoComposite(offscreen_context_provider,
+ frame_begin_time,
+ device_viewport_damage_rect,
+ frame);
layer_tree_host_->DidBeginFrame();
return result;
}
@@ -397,7 +413,9 @@ bool SingleThreadProxy::ShouldComposite() const {
bool SingleThreadProxy::DoComposite(
scoped_refptr<cc::ContextProvider> offscreen_context_provider,
- base::TimeTicks frame_begin_time) {
+ base::TimeTicks frame_begin_time,
+ gfx::Rect device_viewport_damage_rect,
+ LayerTreeHostImpl::FrameData* frame) {
DCHECK(!output_surface_lost_);
{
DebugScopedSetImplThread impl(this);
@@ -418,10 +436,9 @@ bool SingleThreadProxy::DoComposite(
layer_tree_host_impl_->Animate(base::TimeTicks::Now(), base::Time::Now());
layer_tree_host_impl_->UpdateBackgroundAnimateTicking(false);
- LayerTreeHostImpl::FrameData frame;
- layer_tree_host_impl_->PrepareToDraw(&frame);
- layer_tree_host_impl_->DrawLayers(&frame, frame_begin_time);
- layer_tree_host_impl_->DidDrawAllLayers(frame);
+ layer_tree_host_impl_->PrepareToDraw(frame, device_viewport_damage_rect);
+ layer_tree_host_impl_->DrawLayers(frame, frame_begin_time);
+ layer_tree_host_impl_->DidDrawAllLayers(*frame);
output_surface_lost_ = layer_tree_host_impl_->IsContextLost();
bool start_ready_animations = true;
diff --git a/cc/trees/single_thread_proxy.h b/cc/trees/single_thread_proxy.h
index 1375620..bfd054d 100644
--- a/cc/trees/single_thread_proxy.h
+++ b/cc/trees/single_thread_proxy.h
@@ -78,11 +78,15 @@ class SingleThreadProxy : public Proxy, LayerTreeHostImplClient {
private:
explicit SingleThreadProxy(LayerTreeHost* layer_tree_host);
- bool CommitAndComposite(base::TimeTicks frame_begin_time);
+ bool CommitAndComposite(base::TimeTicks frame_begin_time,
+ gfx::Rect device_viewport_damage_rect,
+ LayerTreeHostImpl::FrameData* frame);
void DoCommit(scoped_ptr<ResourceUpdateQueue> queue);
bool DoComposite(
scoped_refptr<cc::ContextProvider> offscreen_context_provider,
- base::TimeTicks frame_begin_time);
+ base::TimeTicks frame_begin_time,
+ gfx::Rect device_viewport_damage_rect,
+ LayerTreeHostImpl::FrameData* frame);
void DidSwapFrame();
bool ShouldComposite() const;
diff --git a/cc/trees/thread_proxy.cc b/cc/trees/thread_proxy.cc
index 2ec6f7d..f824c9b 100644
--- a/cc/trees/thread_proxy.cc
+++ b/cc/trees/thread_proxy.cc
@@ -894,6 +894,11 @@ ThreadProxy::ScheduledActionDrawAndSwapInternal(bool forced_draw) {
// DrawLayers() depends on the result of PrepareToDraw(), it is guarded on
// CanDraw() as well.
+ // If it is a forced draw, make sure we do a draw and swap.
+ gfx::Rect readback_rect;
+ if (readback_request_on_impl_thread_)
+ readback_rect = readback_request_on_impl_thread_->rect;
+
LayerTreeHostImpl::FrameData frame;
bool draw_frame = false;
bool start_ready_animations = true;
@@ -901,7 +906,8 @@ ThreadProxy::ScheduledActionDrawAndSwapInternal(bool forced_draw) {
if (layer_tree_host_impl_->CanDraw()) {
// Do not start animations if we skip drawing the frame to avoid
// checkerboarding.
- if (layer_tree_host_impl_->PrepareToDraw(&frame) || forced_draw)
+ if (layer_tree_host_impl_->PrepareToDraw(&frame, readback_rect) ||
+ forced_draw)
draw_frame = true;
else
start_ready_animations = false;
@@ -939,7 +945,7 @@ ThreadProxy::ScheduledActionDrawAndSwapInternal(bool forced_draw) {
readback_request_on_impl_thread_->completion.Signal();
readback_request_on_impl_thread_ = NULL;
} else if (draw_frame) {
- result.did_swap = layer_tree_host_impl_->SwapBuffers();
+ result.did_swap = layer_tree_host_impl_->SwapBuffers(frame);
if (frame.contains_incomplete_tile)
DidSwapUseIncompleteTileOnImplThread();