cc: Ensure changes to a Layer's content bounds or scale get pushed
This changes UpdateLayerContentsScale(Layer* layer, ...) so that if
the layer's content bounds or contents scale are changed, then its
needs_push_properties() flag is set.
BUG=345267
Review URL: https://codereview.chromium.org/178303002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@253140 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/cc/layers/layer.h b/cc/layers/layer.h
index 2f891ec..37772e9 100644
--- a/cc/layers/layer.h
+++ b/cc/layers/layer.h
@@ -440,10 +440,14 @@
virtual bool SupportsLCDText() const;
+ void SetNeedsPushProperties();
bool needs_push_properties() const { return needs_push_properties_; }
bool descendant_needs_push_properties() const {
return num_dependents_need_push_properties_ > 0;
}
+ void reset_needs_push_properties_for_testing() {
+ needs_push_properties_ = false;
+ }
virtual void RunMicroBenchmark(MicroBenchmark* benchmark);
@@ -476,7 +480,6 @@
// Called when the blend mode or filters have been changed.
void SetNeedsFilterContextIfNeeded();
- void SetNeedsPushProperties();
void AddDependentNeedsPushProperties();
void RemoveDependentNeedsPushProperties();
bool parent_should_know_need_push_properties() const {
diff --git a/cc/trees/layer_tree_host_common.cc b/cc/trees/layer_tree_host_common.cc
index 9f652d9..ddee3930 100644
--- a/cc/trees/layer_tree_host_common.cc
+++ b/cc/trees/layer_tree_host_common.cc
@@ -989,6 +989,9 @@
if (!layer->raster_scale_is_unknown())
raster_scale = layer->raster_scale();
+ gfx::Size old_content_bounds = layer->content_bounds();
+ float old_contents_scale_x = layer->contents_scale_x();
+ float old_contents_scale_y = layer->contents_scale_y();
float contents_scale = raster_scale * device_scale_factor * page_scale_factor;
CalculateContentsScale(layer,
@@ -996,6 +999,11 @@
device_scale_factor,
page_scale_factor,
animating_transform_to_screen);
+
+ if (layer->content_bounds() != old_content_bounds ||
+ layer->contents_scale_x() != old_contents_scale_x ||
+ layer->contents_scale_y() != old_contents_scale_y)
+ layer->SetNeedsPushProperties();
}
static inline RenderSurface* CreateOrReuseRenderSurface(Layer* layer) {
diff --git a/cc/trees/layer_tree_host_common_unittest.cc b/cc/trees/layer_tree_host_common_unittest.cc
index 43df32ae..7099883 100644
--- a/cc/trees/layer_tree_host_common_unittest.cc
+++ b/cc/trees/layer_tree_host_common_unittest.cc
@@ -7223,6 +7223,58 @@
}
}
+TEST_F(LayerTreeHostCommonTest,
+ ChangeInContentBoundsOrScaleTriggersPushProperties) {
+ MockContentLayerClient delegate;
+ scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<Layer> child = CreateDrawableContentLayer(&delegate);
+ root->AddChild(child);
+
+ scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
+ host->SetRootLayer(root);
+
+ gfx::Transform identity_matrix;
+ SetLayerPropertiesForTesting(root.get(),
+ identity_matrix,
+ gfx::PointF(),
+ gfx::PointF(),
+ gfx::Size(100, 100),
+ true,
+ false);
+ SetLayerPropertiesForTesting(child.get(),
+ identity_matrix,
+ gfx::PointF(),
+ gfx::PointF(),
+ gfx::Size(100, 100),
+ true,
+ false);
+
+ root->reset_needs_push_properties_for_testing();
+ child->reset_needs_push_properties_for_testing();
+
+ // This will change both layers' content bounds.
+ ExecuteCalculateDrawProperties(root.get());
+ EXPECT_TRUE(root->needs_push_properties());
+ EXPECT_TRUE(child->needs_push_properties());
+
+ root->reset_needs_push_properties_for_testing();
+ child->reset_needs_push_properties_for_testing();
+
+ // This will change only the child layer's contents scale and content bounds,
+ // since the root layer is not a ContentsScalingLayer.
+ ExecuteCalculateDrawProperties(root.get(), 2.f);
+ EXPECT_FALSE(root->needs_push_properties());
+ EXPECT_TRUE(child->needs_push_properties());
+
+ root->reset_needs_push_properties_for_testing();
+ child->reset_needs_push_properties_for_testing();
+
+ // This will not change either layer's contents scale or content bounds.
+ ExecuteCalculateDrawProperties(root.get(), 2.f);
+ EXPECT_FALSE(root->needs_push_properties());
+ EXPECT_FALSE(child->needs_push_properties());
+}
+
TEST_F(LayerTreeHostCommonTest, RenderSurfaceTransformsInHighDPI) {
MockContentLayerClient delegate;
gfx::Transform identity_matrix;
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc
index eb81d5b..d56ba21 100644
--- a/cc/trees/layer_tree_host_unittest.cc
+++ b/cc/trees/layer_tree_host_unittest.cc
@@ -817,6 +817,77 @@
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestUndrawnLayersDamageLater);
+// Tests that if a layer is not drawn because of some reason in the parent,
+// causing its content bounds to not be computed, then when it is later drawn,
+// its content bounds get pushed.
+class LayerTreeHostTestUndrawnLayersPushContentBoundsLater
+ : public LayerTreeHostTest {
+ public:
+ LayerTreeHostTestUndrawnLayersPushContentBoundsLater()
+ : root_layer_(Layer::Create()) {}
+
+ virtual void SetupTree() OVERRIDE {
+ root_layer_->SetIsDrawable(true);
+ root_layer_->SetBounds(gfx::Size(20, 20));
+ layer_tree_host()->SetRootLayer(root_layer_);
+
+ parent_layer_ = Layer::Create();
+ parent_layer_->SetBounds(gfx::Size(20, 20));
+ parent_layer_->SetOpacity(0.0f);
+ root_layer_->AddChild(parent_layer_);
+
+ child_layer_ = Layer::Create();
+ child_layer_->SetBounds(gfx::Size(15, 15));
+ parent_layer_->AddChild(child_layer_);
+
+ LayerTreeHostTest::SetupTree();
+ }
+
+ virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
+
+ virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
+ LayerImpl* root = host_impl->active_tree()->root_layer();
+ LayerImpl* parent = root->children()[0];
+ LayerImpl* child = parent->children()[0];
+
+ switch (host_impl->active_tree()->source_frame_number()) {
+ case 0:
+ EXPECT_EQ(0.f, parent->opacity());
+ EXPECT_EQ(gfx::SizeF(), child->content_bounds());
+ break;
+ case 1:
+ EXPECT_EQ(1.f, parent->opacity());
+ EXPECT_EQ(gfx::SizeF(15.f, 15.f), child->content_bounds());
+ EndTest();
+ break;
+ default:
+ NOTREACHED();
+ }
+ }
+
+ virtual void DidCommit() OVERRIDE {
+ switch (layer_tree_host()->source_frame_number()) {
+ case 1:
+ parent_layer_->SetOpacity(1.0f);
+ break;
+ case 2:
+ break;
+ default:
+ NOTREACHED();
+ }
+ }
+
+ virtual void AfterTest() OVERRIDE {}
+
+ private:
+ scoped_refptr<Layer> root_layer_;
+ scoped_refptr<Layer> parent_layer_;
+ scoped_refptr<Layer> child_layer_;
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(
+ LayerTreeHostTestUndrawnLayersPushContentBoundsLater);
+
// If the layerTreeHost says it can't draw, Then we should not try to draw.
class LayerTreeHostTestCanDrawBlocksDrawing : public LayerTreeHostTest {
public: