diff options
author | danakj <danakj@chromium.org> | 2015-02-13 19:08:05 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-02-14 03:08:48 +0000 |
commit | 72ab277eeae83cccf8ceddd42398b6bf4f943c69 (patch) | |
tree | 1b119b245f70223706dae5cb8fadf553c9b50aa7 /cc | |
parent | 233eb509fd4b7d8463515ca57a16d725bf76764c (diff) | |
download | chromium_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.cc | 7 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_unittest_picture.cc | 238 | ||||
-rw-r--r-- | cc/trees/layer_tree_impl.cc | 1 |
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; |