summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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
-rw-r--r--webkit/compositor_bindings/web_layer_unittest.cc7
6 files changed, 99 insertions, 28 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());
diff --git a/webkit/compositor_bindings/web_layer_unittest.cc b/webkit/compositor_bindings/web_layer_unittest.cc
index cf77e97..7813b36 100644
--- a/webkit/compositor_bindings/web_layer_unittest.cc
+++ b/webkit/compositor_bindings/web_layer_unittest.cc
@@ -104,10 +104,11 @@ TEST_F(WebLayerTest, Client)
EXPECT_TRUE(layer->masksToBounds());
EXPECT_CALL(m_client, scheduleComposite()).Times(AnyNumber());
- scoped_ptr<WebLayer> otherLayer(new WebLayerImpl);
- m_rootLayer->addChild(otherLayer.get());
+ scoped_ptr<WebLayer> otherLayer1(new WebLayerImpl);
+ m_rootLayer->addChild(otherLayer1.get());
EXPECT_CALL(m_client, scheduleComposite()).Times(AtLeast(1));
- layer->setMaskLayer(otherLayer.get());
+ scoped_ptr<WebLayer> otherLayer2(new WebLayerImpl);
+ layer->setMaskLayer(otherLayer2.get());
Mock::VerifyAndClearExpectations(&m_client);
EXPECT_CALL(m_client, scheduleComposite()).Times(AtLeast(1));