summaryrefslogtreecommitdiffstats
path: root/cc
diff options
context:
space:
mode:
authordanakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-02-22 22:59:37 +0000
committerdanakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-02-22 22:59:37 +0000
commit4e4efcc0bd72d02fac61e54f995b8e798664ae32 (patch)
tree7e17df4dc3b8e73ff1efcae29a167d17733e282a /cc
parentc5d10e573121524977394fa3bc0ed2bcea25b2b1 (diff)
downloadchromium_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.cc56
-rw-r--r--cc/layer.h2
-rw-r--r--cc/layer_impl.cc10
-rw-r--r--cc/layer_impl.h1
-rw-r--r--cc/layer_unittest.cc51
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();
}
diff --git a/cc/layer.h b/cc/layer.h
index d31fe84..cf0d396 100644
--- a/cc/layer.h
+++ b/cc/layer.h
@@ -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());