Bug 1328702: ContainerLayer::RemoveAllChildren implementation. r=kats,mattwoodrow

MozReview-Commit-ID: 6zC3v8dQcWD
This commit is contained in:
Milan Sreckovic
2017-01-05 13:41:10 -05:00
parent bfca49082b
commit 3ab9239a2b
4 changed files with 49 additions and 8 deletions

View File

@@ -1182,6 +1182,43 @@ ContainerLayer::InsertAfter(Layer* aChild, Layer* aAfter)
return true; return true;
} }
void
ContainerLayer::RemoveAllChildren()
{
// Optimizes "while (mFirstChild) ContainerLayer::RemoveChild(mFirstChild);"
Layer* current = mFirstChild;
// This is inlining DidRemoveChild() on each layer; we can skip the calls
// to NotifyPaintedLayerRemoved as it gets taken care of when as we call
// NotifyRemoved prior to removing any layers.
while (current) {
Layer* next = current->GetNextSibling();
if (current->GetType() == TYPE_READBACK) {
static_cast<ReadbackLayer*>(current)->NotifyRemoved();
}
current = next;
}
current = mFirstChild;
mFirstChild = nullptr;
while (current) {
MOZ_ASSERT(!current->GetPrevSibling());
Layer* next = current->GetNextSibling();
current->SetParent(nullptr);
current->SetNextSibling(nullptr);
if (next) {
next->SetPrevSibling(nullptr);
}
NS_RELEASE(current);
current = next;
}
}
// Note that ContainerLayer::RemoveAllChildren is an optimized
// version of this code; if you make changes to ContainerLayer::RemoveChild
// consider whether the matching changes need to be made to
// ContainerLayer::RemoveAllChildren
bool bool
ContainerLayer::RemoveChild(Layer *aChild) ContainerLayer::RemoveChild(Layer *aChild)
{ {
@@ -1625,6 +1662,10 @@ ContainerLayer::HasOpaqueAncestorLayer(Layer* aLayer)
return false; return false;
} }
// Note that ContainerLayer::RemoveAllChildren contains an optimized
// version of this code; if you make changes to ContainerLayer::DidRemoveChild
// consider whether the matching changes need to be made to
// ContainerLayer::RemoveAllChildren
void void
ContainerLayer::DidRemoveChild(Layer* aLayer) ContainerLayer::DidRemoveChild(Layer* aLayer)
{ {

View File

@@ -2257,6 +2257,12 @@ public:
protected: protected:
friend class ReadbackProcessor; friend class ReadbackProcessor;
// Note that this is not virtual, and is based on the implementation of
// ContainerLayer::RemoveChild, so it should only be called where you would
// want to explicitly call the base class implementation of RemoveChild;
// e.g., while (mFirstChild) ContainerLayer::RemoveChild(mFirstChild);
void RemoveAllChildren();
void DidInsertChild(Layer* aLayer); void DidInsertChild(Layer* aLayer);
void DidRemoveChild(Layer* aLayer); void DidRemoveChild(Layer* aLayer);

View File

@@ -23,10 +23,7 @@ namespace layers {
BasicContainerLayer::~BasicContainerLayer() BasicContainerLayer::~BasicContainerLayer()
{ {
while (mFirstChild) { ContainerLayer::RemoveAllChildren();
ContainerLayer::RemoveChild(mFirstChild);
}
MOZ_COUNT_DTOR(BasicContainerLayer); MOZ_COUNT_DTOR(BasicContainerLayer);
} }

View File

@@ -36,10 +36,7 @@ public:
protected: protected:
virtual ~ClientContainerLayer() virtual ~ClientContainerLayer()
{ {
while (mFirstChild) { ContainerLayer::RemoveAllChildren();
ContainerLayer::RemoveChild(mFirstChild);
}
MOZ_COUNT_DTOR(ClientContainerLayer); MOZ_COUNT_DTOR(ClientContainerLayer);
} }