diff options
author | danakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-02-22 22:59:37 +0000 |
---|---|---|
committer | danakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-02-22 22:59:37 +0000 |
commit | 4e4efcc0bd72d02fac61e54f995b8e798664ae32 (patch) | |
tree | 7e17df4dc3b8e73ff1efcae29a167d17733e282a /cc | |
parent | c5d10e573121524977394fa3bc0ed2bcea25b2b1 (diff) | |
download | chromium_src-4e4efcc0bd72d02fac61e54f995b8e798664ae32.zip chromium_src-4e4efcc0bd72d02fac61e54f995b8e798664ae32.tar.gz chromium_src-4e4efcc0bd72d02fac61e54f995b8e798664ae32.tar.bz2 |
cc: Give mask and replica layers a parent.
Mask and replica layers hang off of another layer in the tree. They are
not strictly children of the layer but they are attached to it. This
patch lets them find the layer they are hanging off, and calls that
the layer's parent. We then call them a "dependent" of the layer rather
than a "child" to distinguish them but still denote a bidirectional
relationship.
This will allow us to early out for entire subtrees in the push-properties
tree walk (and potentially other tree walks as well), to greatly speed up
commit.
Tested by LayerTest.maskAndReplicaHasParent
BUG=177756
NOTRY=true
Review URL: https://chromiumcodereview.appspot.com/12334046
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@184203 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc')
-rw-r--r-- | cc/layer.cc | 56 | ||||
-rw-r--r-- | cc/layer.h | 2 | ||||
-rw-r--r-- | cc/layer_impl.cc | 10 | ||||
-rw-r--r-- | cc/layer_impl.h | 1 | ||||
-rw-r--r-- | cc/layer_unittest.cc | 51 |
5 files changed, 95 insertions, 25 deletions
diff --git a/cc/layer.cc b/cc/layer.cc index d78afaf..c3ac483 100644 --- a/cc/layer.cc +++ b/cc/layer.cc @@ -74,8 +74,16 @@ Layer::~Layer() m_layerAnimationController->removeObserver(this); - // Remove the parent reference from all children. + // Remove the parent reference from all children and dependents. removeAllChildren(); + if (m_maskLayer) { + DCHECK_EQ(this, m_maskLayer->parent()); + m_maskLayer->removeFromParent(); + } + if (m_replicaLayer) { + DCHECK_EQ(this, m_replicaLayer->parent()); + m_replicaLayer->removeFromParent(); + } } void Layer::setLayerTreeHost(LayerTreeHost* host) @@ -158,6 +166,10 @@ void Layer::setParent(Layer* layer) setLayerTreeHost(m_parent ? m_parent->layerTreeHost() : 0); forceAutomaticRasterScaleToBeRecomputed(); + if (m_maskLayer) + m_maskLayer->forceAutomaticRasterScaleToBeRecomputed(); + if (m_replicaLayer && m_replicaLayer->m_maskLayer) + m_replicaLayer->m_maskLayer->forceAutomaticRasterScaleToBeRecomputed(); } bool Layer::hasAncestor(Layer* ancestor) const @@ -188,11 +200,24 @@ void Layer::insertChild(scoped_refptr<Layer> child, size_t index) void Layer::removeFromParent() { if (m_parent) - m_parent->removeChild(this); + m_parent->removeChildOrDependent(this); } -void Layer::removeChild(Layer* child) +void Layer::removeChildOrDependent(Layer* child) { + if (m_maskLayer == child) { + m_maskLayer->setParent(NULL); + m_maskLayer = NULL; + setNeedsFullTreeSync(); + return; + } + if (m_replicaLayer == child) { + m_replicaLayer->setParent(NULL); + m_replicaLayer = NULL; + setNeedsFullTreeSync(); + return; + } + for (LayerList::iterator iter = m_children.begin(); iter != m_children.end(); ++iter) { if (*iter != child) @@ -270,7 +295,7 @@ void Layer::removeAllChildren() { while (m_children.size()) { Layer* layer = m_children[0].get(); - DCHECK(layer->parent()); + DCHECK_EQ(this, layer->parent()); layer->removeFromParent(); } } @@ -339,11 +364,15 @@ void Layer::setMaskLayer(Layer* maskLayer) { if (m_maskLayer == maskLayer) return; - if (m_maskLayer) - m_maskLayer->setLayerTreeHost(0); + if (m_maskLayer) { + DCHECK_EQ(this, m_maskLayer->parent()); + m_maskLayer->removeFromParent(); + } m_maskLayer = maskLayer; if (m_maskLayer) { - m_maskLayer->setLayerTreeHost(m_layerTreeHost); + DCHECK(!m_maskLayer->parent()); + m_maskLayer->removeFromParent(); + m_maskLayer->setParent(this); m_maskLayer->setIsMask(true); } setNeedsFullTreeSync(); @@ -353,11 +382,16 @@ void Layer::setReplicaLayer(Layer* layer) { if (m_replicaLayer == layer) return; - if (m_replicaLayer) - m_replicaLayer->setLayerTreeHost(0); + if (m_replicaLayer) { + DCHECK_EQ(this, m_replicaLayer->parent()); + m_replicaLayer->removeFromParent(); + } m_replicaLayer = layer; - if (m_replicaLayer) - m_replicaLayer->setLayerTreeHost(m_layerTreeHost); + if (m_replicaLayer) { + DCHECK(!m_replicaLayer->parent()); + m_replicaLayer->removeFromParent(); + m_replicaLayer->setParent(this); + } setNeedsFullTreeSync(); } @@ -339,7 +339,7 @@ private: int indexOfChild(const Layer*); // This should only be called from removeFromParent. - void removeChild(Layer*); + void removeChildOrDependent(Layer*); // LayerAnimationValueObserver implementation. virtual void OnOpacityAnimated(float) OVERRIDE; diff --git a/cc/layer_impl.cc b/cc/layer_impl.cc index 7838cb1..cc1bb1f 100644 --- a/cc/layer_impl.cc +++ b/cc/layer_impl.cc @@ -102,12 +102,6 @@ scoped_ptr<LayerImpl> LayerImpl::removeChild(LayerImpl* child) return scoped_ptr<LayerImpl>(); } -void LayerImpl::removeAllChildren() -{ - m_children.clear(); - layerTreeImpl()->set_needs_update_draw_properties(); -} - void LayerImpl::clearChildList() { if (m_children.empty()) @@ -606,6 +600,8 @@ void LayerImpl::setMaskLayer(scoped_ptr<LayerImpl> maskLayer) m_maskLayer = maskLayer.Pass(); m_maskLayerId = newLayerId; + if (m_maskLayer) + m_maskLayer->setParent(this); noteLayerPropertyChangedForSubtree(); } @@ -627,6 +623,8 @@ void LayerImpl::setReplicaLayer(scoped_ptr<LayerImpl> replicaLayer) m_replicaLayer = replicaLayer.Pass(); m_replicaLayerId = newLayerId; + if (m_replicaLayer) + m_replicaLayer->setParent(this); noteLayerPropertyChangedForSubtree(); } diff --git a/cc/layer_impl.h b/cc/layer_impl.h index c168964..20b2384 100644 --- a/cc/layer_impl.h +++ b/cc/layer_impl.h @@ -72,7 +72,6 @@ public: LayerImpl* childAt(size_t index) const; void addChild(scoped_ptr<LayerImpl>); scoped_ptr<LayerImpl> removeChild(LayerImpl* child); - void removeAllChildren(); void setParent(LayerImpl* parent) { m_parent = parent; } void clearChildList(); // Warning: This does not preserve tree structure invariants. diff --git a/cc/layer_unittest.cc b/cc/layer_unittest.cc index 6784858..5eb9e2e 100644 --- a/cc/layer_unittest.cc +++ b/cc/layer_unittest.cc @@ -535,7 +535,8 @@ TEST_F(LayerTest, checkPropertyChangeCausesCorrectBehavior) testLayer->setLayerTreeHost(m_layerTreeHost.get()); EXPECT_SET_NEEDS_COMMIT(1, testLayer->setIsDrawable(true)); - scoped_refptr<Layer> dummyLayer = Layer::create(); // just a dummy layer for this test case. + scoped_refptr<Layer> dummyLayer1 = Layer::create(); // just a dummy layer for this test case. + scoped_refptr<Layer> dummyLayer2 = Layer::create(); // just a dummy layer for this test case. // sanity check of initial test condition EXPECT_FALSE(testLayer->needsDisplayForTesting()); @@ -561,11 +562,14 @@ TEST_F(LayerTest, checkPropertyChangeCausesCorrectBehavior) EXPECT_SET_NEEDS_COMMIT(1, testLayer->setDrawCheckerboardForMissingTiles(!testLayer->drawCheckerboardForMissingTiles())); EXPECT_SET_NEEDS_COMMIT(1, testLayer->setForceRenderSurface(true)); - EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, testLayer->setMaskLayer(dummyLayer.get())); - EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, testLayer->setReplicaLayer(dummyLayer.get())); + EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, testLayer->setMaskLayer(dummyLayer1.get())); + EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, testLayer->setReplicaLayer(dummyLayer2.get())); // The above tests should not have caused a change to the needsDisplay flag. EXPECT_FALSE(testLayer->needsDisplayForTesting()); + + // As layers are removed from the tree, they will cause a tree sync. + EXPECT_CALL(*m_layerTreeHost, setNeedsFullTreeSync()).Times((AnyNumber())); } TEST_F(LayerTest, setBoundsTriggersSetNeedsRedrawAfterGettingNonEmptyBounds) @@ -639,6 +643,42 @@ TEST_F(LayerTest, verifyPushPropertiesCausesSurfacePropertyChangedForOpacity) EXPECT_TRUE(implLayer->layerSurfacePropertyChanged()); } +TEST_F(LayerTest, maskAndReplicaHasParent) +{ + scoped_refptr<Layer> parent = Layer::create(); + scoped_refptr<Layer> child = Layer::create(); + scoped_refptr<Layer> mask = Layer::create(); + scoped_refptr<Layer> replica = Layer::create(); + scoped_refptr<Layer> replicaMask = Layer::create(); + scoped_refptr<Layer> maskReplacement = Layer::create(); + scoped_refptr<Layer> replicaReplacement = Layer::create(); + scoped_refptr<Layer> replicaMaskReplacement = Layer::create(); + + parent->addChild(child); + child->setMaskLayer(mask.get()); + child->setReplicaLayer(replica.get()); + replica->setMaskLayer(replicaMask.get()); + + EXPECT_EQ(parent, child->parent()); + EXPECT_EQ(child, mask->parent()); + EXPECT_EQ(child, replica->parent()); + EXPECT_EQ(replica, replicaMask->parent()); + + replica->setMaskLayer(replicaMaskReplacement.get()); + EXPECT_EQ(NULL, replicaMask->parent()); + EXPECT_EQ(replica, replicaMaskReplacement->parent()); + + child->setMaskLayer(maskReplacement.get()); + EXPECT_EQ(NULL, mask->parent()); + EXPECT_EQ(child, maskReplacement->parent()); + + child->setReplicaLayer(replicaReplacement.get()); + EXPECT_EQ(NULL, replica->parent()); + EXPECT_EQ(child, replicaReplacement->parent()); + + EXPECT_EQ(replica, replica->maskLayer()->parent()); +} + class FakeLayerImplTreeHost : public LayerTreeHost { public: static scoped_ptr<FakeLayerImplTreeHost> create() @@ -672,7 +712,6 @@ void assertLayerTreeHostMatchesForSubtree(Layer* layer, LayerTreeHost* host) assertLayerTreeHostMatchesForSubtree(layer->replicaLayer(), host); } - TEST(LayerLayerTreeHostTest, enteringTree) { scoped_refptr<Layer> parent = Layer::create(); @@ -685,7 +724,7 @@ TEST(LayerLayerTreeHostTest, enteringTree) parent->addChild(child); child->setMaskLayer(mask.get()); child->setReplicaLayer(replica.get()); - replica->setMaskLayer(mask.get()); + replica->setMaskLayer(replicaMask.get()); assertLayerTreeHostMatchesForSubtree(parent.get(), 0); @@ -741,7 +780,7 @@ TEST(LayerLayerTreeHostTest, changeHost) parent->addChild(child); child->setMaskLayer(mask.get()); child->setReplicaLayer(replica.get()); - replica->setMaskLayer(mask.get()); + replica->setMaskLayer(replicaMask.get()); scoped_ptr<FakeLayerImplTreeHost> firstLayerTreeHost(FakeLayerImplTreeHost::create()); firstLayerTreeHost->setRootLayer(parent.get()); |