summaryrefslogtreecommitdiffstats
path: root/cc
diff options
context:
space:
mode:
authordanakj <danakj@chromium.org>2015-02-13 19:08:05 -0800
committerCommit bot <commit-bot@chromium.org>2015-02-14 03:08:48 +0000
commit72ab277eeae83cccf8ceddd42398b6bf4f943c69 (patch)
tree1b119b245f70223706dae5cb8fadf553c9b50aa7 /cc
parent233eb509fd4b7d8463515ca57a16d725bf76764c (diff)
downloadchromium_src-72ab277eeae83cccf8ceddd42398b6bf4f943c69.zip
chromium_src-72ab277eeae83cccf8ceddd42398b6bf4f943c69.tar.gz
chromium_src-72ab277eeae83cccf8ceddd42398b6bf4f943c69.tar.bz2
cc: Fix DCHECK when impl thread changes scale on a layer being hidden.
If a layer is being hidden (no longer part of the RenderSurfaceLayerList), then we will not UpdateTiles to add tilings to it. If scales change on the active tree, the recycle tree will lose its tilings, then the hidden layer will have 0 tilings on the pending tree. In this case, instead of keeping the non-ideal tilings on the active tree, and having no high-res tiling, drop the non-ideal tilings from the active tree. R=enne, vmpstr BUG=446751 Review URL: https://codereview.chromium.org/924213002 Cr-Commit-Position: refs/heads/master@{#316368}
Diffstat (limited to 'cc')
-rw-r--r--cc/resources/picture_layer_tiling_set.cc7
-rw-r--r--cc/trees/layer_tree_host_unittest_picture.cc238
-rw-r--r--cc/trees/layer_tree_impl.cc1
3 files changed, 245 insertions, 1 deletions
diff --git a/cc/resources/picture_layer_tiling_set.cc b/cc/resources/picture_layer_tiling_set.cc
index e1659be..d931543 100644
--- a/cc/resources/picture_layer_tiling_set.cc
+++ b/cc/resources/picture_layer_tiling_set.cc
@@ -65,6 +65,13 @@ void PictureLayerTilingSet::UpdateTilingsToCurrentRasterSource(
// Copy over tilings that are shared with the |twin_set| tiling set (if it
// exists).
if (twin_set) {
+ if (twin_set->tilings_.empty()) {
+ // If the twin (pending) tiling set is empty, it was not updated for the
+ // current frame. So we drop tilings from our set as well, instead of
+ // leaving behind unshared tilings that are all non-ideal.
+ RemoveAllTilings();
+ }
+
for (PictureLayerTiling* twin_tiling : twin_set->tilings_) {
float contents_scale = twin_tiling->contents_scale();
DCHECK_GE(contents_scale, minimum_contents_scale);
diff --git a/cc/trees/layer_tree_host_unittest_picture.cc b/cc/trees/layer_tree_host_unittest_picture.cc
index 159200a..d4c34bd 100644
--- a/cc/trees/layer_tree_host_unittest_picture.cc
+++ b/cc/trees/layer_tree_host_unittest_picture.cc
@@ -327,5 +327,243 @@ class LayerTreeHostPictureTestChangeLiveTilesRectWithRecycleTree
SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(
LayerTreeHostPictureTestChangeLiveTilesRectWithRecycleTree);
+class LayerTreeHostPictureTestRSLLMembership : public LayerTreeHostPictureTest {
+ void SetupTree() override {
+ scoped_refptr<Layer> root = Layer::Create();
+ root->SetBounds(gfx::Size(100, 100));
+
+ child_ = Layer::Create();
+ root->AddChild(child_);
+
+ // Don't be solid color so the layer has tilings/tiles.
+ client_.set_fill_with_nonsolid_color(true);
+ picture_ = FakePictureLayer::Create(&client_);
+ picture_->SetBounds(gfx::Size(100, 100));
+ child_->AddChild(picture_);
+
+ layer_tree_host()->SetRootLayer(root);
+ LayerTreeHostPictureTest::SetupTree();
+ }
+
+ void BeginTest() override { PostSetNeedsCommitToMainThread(); }
+
+ void WillActivateTreeOnThread(LayerTreeHostImpl* impl) override {
+ LayerImpl* root = impl->sync_tree()->root_layer();
+ LayerImpl* child = root->children()[0];
+ LayerImpl* gchild = child->children()[0];
+ FakePictureLayerImpl* picture = static_cast<FakePictureLayerImpl*>(gchild);
+
+ switch (impl->sync_tree()->source_frame_number()) {
+ case 0:
+ // On 1st commit the layer has tilings.
+ EXPECT_GT(picture->tilings()->num_tilings(), 0u);
+ break;
+ case 1:
+ // On 2nd commit, the layer is transparent, but its tilings are left
+ // there.
+ EXPECT_GT(picture->tilings()->num_tilings(), 0u);
+ break;
+ case 2:
+ // On 3rd commit, the layer is visible again, so has tilings.
+ EXPECT_GT(picture->tilings()->num_tilings(), 0u);
+ }
+ }
+
+ void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override {
+ LayerImpl* root = impl->active_tree()->root_layer();
+ LayerImpl* child = root->children()[0];
+ LayerImpl* gchild = child->children()[0];
+ FakePictureLayerImpl* picture = static_cast<FakePictureLayerImpl*>(gchild);
+
+ switch (impl->active_tree()->source_frame_number()) {
+ case 0:
+ // On 1st commit the layer has tilings.
+ EXPECT_GT(picture->tilings()->num_tilings(), 0u);
+ break;
+ case 1:
+ // On 2nd commit, the layer is transparent, but its tilings are left
+ // there.
+ EXPECT_GT(picture->tilings()->num_tilings(), 0u);
+ break;
+ case 2:
+ // On 3rd commit, the layer is visible again, so has tilings.
+ EXPECT_GT(picture->tilings()->num_tilings(), 0u);
+ EndTest();
+ }
+ }
+
+ void DidCommit() override {
+ switch (layer_tree_host()->source_frame_number()) {
+ case 1:
+ // For the 2nd commit, change opacity to 0 so that the layer will not be
+ // part of the visible frame.
+ child_->SetOpacity(0.f);
+ break;
+ case 2:
+ // For the 3rd commit, change opacity to 1 so that the layer will again
+ // be part of the visible frame.
+ child_->SetOpacity(1.f);
+ }
+ }
+
+ void AfterTest() override {}
+
+ FakeContentLayerClient client_;
+ scoped_refptr<Layer> child_;
+ scoped_refptr<FakePictureLayer> picture_;
+};
+
+SINGLE_AND_MULTI_THREAD_IMPL_TEST_F(LayerTreeHostPictureTestRSLLMembership);
+
+class LayerTreeHostPictureTestRSLLMembershipWithScale
+ : public LayerTreeHostPictureTest {
+ void SetupTree() override {
+ scoped_refptr<Layer> root = Layer::Create();
+ root->SetBounds(gfx::Size(100, 100));
+
+ pinch_ = Layer::Create();
+ pinch_->SetBounds(gfx::Size(500, 500));
+ pinch_->SetScrollClipLayerId(root->id());
+ pinch_->SetIsContainerForFixedPositionLayers(true);
+ root->AddChild(pinch_);
+
+ // Don't be solid color so the layer has tilings/tiles.
+ client_.set_fill_with_nonsolid_color(true);
+ picture_ = FakePictureLayer::Create(&client_);
+ picture_->SetBounds(gfx::Size(100, 100));
+ pinch_->AddChild(picture_);
+
+ layer_tree_host()->RegisterViewportLayers(NULL, root, pinch_, pinch_);
+ layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f);
+ layer_tree_host()->SetRootLayer(root);
+ LayerTreeHostPictureTest::SetupTree();
+ }
+
+ void InitializeSettings(LayerTreeSettings* settings) override {
+ settings->layer_transforms_should_scale_layer_contents = true;
+ }
+
+ void BeginTest() override {
+ frame_ = 0;
+ draws_in_frame_ = 0;
+ last_frame_drawn_ = -1;
+ PostSetNeedsCommitToMainThread();
+ }
+
+ void WillActivateTreeOnThread(LayerTreeHostImpl* impl) override {
+ LayerImpl* root = impl->sync_tree()->root_layer();
+ LayerImpl* pinch = root->children()[0];
+ LayerImpl* gchild = pinch->children()[0];
+ FakePictureLayerImpl* picture = static_cast<FakePictureLayerImpl*>(gchild);
+
+ switch (frame_) {
+ case 0:
+ // On 1st commit the layer has tilings.
+ EXPECT_GT(picture->tilings()->num_tilings(), 0u);
+ break;
+ case 1:
+ // On 2nd commit, the layer is transparent, so does not have tilings.
+ EXPECT_EQ(0u, picture->tilings()->num_tilings());
+ break;
+ case 2:
+ // On 3rd commit, the layer is visible again, so has tilings.
+ EXPECT_GT(picture->tilings()->num_tilings(), 0u);
+ }
+ }
+
+ void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
+ LayerImpl* root = impl->active_tree()->root_layer();
+ LayerImpl* pinch = root->children()[0];
+ LayerImpl* gchild = pinch->children()[0];
+ FakePictureLayerImpl* picture = static_cast<FakePictureLayerImpl*>(gchild);
+
+ if (frame_ != last_frame_drawn_)
+ draws_in_frame_ = 0;
+ ++draws_in_frame_;
+ last_frame_drawn_ = frame_;
+
+ switch (frame_) {
+ case 0:
+ if (draws_in_frame_ == 1) {
+ // On 1st commit the layer has tilings.
+ EXPECT_GT(picture->tilings()->num_tilings(), 0u);
+ EXPECT_EQ(1.f, picture->HighResTiling()->contents_scale());
+
+ // Pinch zoom in to change the scale on the active tree.
+ impl->PinchGestureBegin();
+ impl->PinchGestureUpdate(2.f, gfx::Point(1, 1));
+ impl->PinchGestureEnd();
+ } else if (picture->tilings()->num_tilings() == 1) {
+ // If the pinch gesture caused a commit we could get here with a
+ // pending tree.
+ EXPECT_FALSE(impl->pending_tree());
+ // The active layer now has only a 2.f scale tiling, which means the
+ // recycled layer's tiling is destroyed.
+ EXPECT_EQ(2.f, picture->HighResTiling()->contents_scale());
+ EXPECT_EQ(0u, picture->GetRecycledTwinLayer()
+ ->picture_layer_tiling_set()
+ ->num_tilings());
+
+ ++frame_;
+ MainThreadTaskRunner()->PostTask(
+ FROM_HERE,
+ base::Bind(
+ &LayerTreeHostPictureTestRSLLMembershipWithScale::NextStep,
+ base::Unretained(this)));
+ }
+ break;
+ case 1:
+ EXPECT_EQ(1, draws_in_frame_);
+ // On 2nd commit, the layer is transparent, so does not create
+ // tilings. Since the 1.f tiling was destroyed in the recycle tree, it
+ // has no tilings left. This is propogated to the active tree.
+ EXPECT_EQ(0u, picture->picture_layer_tiling_set()->num_tilings());
+ EXPECT_EQ(0u, picture->GetRecycledTwinLayer()
+ ->picture_layer_tiling_set()
+ ->num_tilings());
+ ++frame_;
+ MainThreadTaskRunner()->PostTask(
+ FROM_HERE,
+ base::Bind(
+ &LayerTreeHostPictureTestRSLLMembershipWithScale::NextStep,
+ base::Unretained(this)));
+ break;
+ case 2:
+ EXPECT_EQ(1, draws_in_frame_);
+ // On 3rd commit, the layer is visible again, so has tilings.
+ EXPECT_GT(picture->tilings()->num_tilings(), 0u);
+ EndTest();
+ }
+ }
+
+ void NextStep() {
+ switch (frame_) {
+ case 1:
+ // For the 2nd commit, change opacity to 0 so that the layer will not be
+ // part of the visible frame.
+ pinch_->SetOpacity(0.f);
+ break;
+ case 2:
+ // For the 3rd commit, change opacity to 1 so that the layer will again
+ // be part of the visible frame.
+ pinch_->SetOpacity(1.f);
+ break;
+ }
+ }
+
+ void AfterTest() override {}
+
+ FakeContentLayerClient client_;
+ scoped_refptr<Layer> pinch_;
+ scoped_refptr<FakePictureLayer> picture_;
+ int frame_;
+ int draws_in_frame_;
+ int last_frame_drawn_;
+};
+
+// Multi-thread only because in single thread you can't pinch zoom on the
+// compositor thread.
+MULTI_THREAD_IMPL_TEST_F(LayerTreeHostPictureTestRSLLMembershipWithScale);
+
} // namespace
} // namespace cc
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc
index 6a64086..4093c42 100644
--- a/cc/trees/layer_tree_impl.cc
+++ b/cc/trees/layer_tree_impl.cc
@@ -657,7 +657,6 @@ bool LayerTreeImpl::UpdateDrawProperties() {
size_t layers_updated_count = 0;
bool tile_priorities_updated = false;
for (PictureLayerImpl* layer : picture_layers_) {
- // TODO(danakj): Remove this to fix crbug.com/446751
if (!layer->IsDrawnRenderSurfaceLayerListMember())
continue;
++layers_updated_count;