Bug 1227231: Use generic tree traversal algorithms for loops over Layer trees. r=botond
Create an Iterator type with classes ForwardIterator and ReverseIterator, having GetFirstChild/GetNextSibling and GetLastChild/GetPrevSibling methods, respectively. Specify the iterator type for each call to ForEachNode. With this, we can support trees with forward and reverse sibling structures. Additionally, apply these algorithms to all Layer recursive traversals, where applicable. Update tests to ensure both directions yield expected results. MozReview-Commit-ID: iYpX22XHTa
This commit is contained in:
@@ -24,6 +24,7 @@
|
||||
#include "nsTArray.h" // for AutoTArray, nsTArray_Impl
|
||||
#include "mozilla/layers/ImageHost.h"
|
||||
#include "mozilla/layers/LayerManagerComposite.h"
|
||||
#include "TreeTraversal.h" // for ForEachNode
|
||||
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
@@ -102,28 +103,28 @@ AddRegion(nsIntRegion& aDest, const nsIntRegion& aSource)
|
||||
* then report that the entire bounds have changed.
|
||||
*/
|
||||
static void
|
||||
NotifySubdocumentInvalidationRecursive(Layer* aLayer, NotifySubDocInvalidationFunc aCallback)
|
||||
NotifySubdocumentInvalidation(Layer* aLayer, NotifySubDocInvalidationFunc aCallback)
|
||||
{
|
||||
aLayer->ClearInvalidRect();
|
||||
ContainerLayer* container = aLayer->AsContainerLayer();
|
||||
|
||||
if (aLayer->GetMaskLayer()) {
|
||||
NotifySubdocumentInvalidationRecursive(aLayer->GetMaskLayer(), aCallback);
|
||||
}
|
||||
for (size_t i = 0; i < aLayer->GetAncestorMaskLayerCount(); i++) {
|
||||
Layer* maskLayer = aLayer->GetAncestorMaskLayerAt(i);
|
||||
NotifySubdocumentInvalidationRecursive(maskLayer, aCallback);
|
||||
}
|
||||
|
||||
if (!container) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (Layer* child = container->GetFirstChild(); child; child = child->GetNextSibling()) {
|
||||
NotifySubdocumentInvalidationRecursive(child, aCallback);
|
||||
}
|
||||
|
||||
aCallback(container, container->GetLocalVisibleRegion().ToUnknownRegion());
|
||||
ForEachNode<ForwardIterator>(
|
||||
aLayer,
|
||||
[aCallback] (Layer* layer)
|
||||
{
|
||||
layer->ClearInvalidRect();
|
||||
if (layer->GetMaskLayer()) {
|
||||
NotifySubdocumentInvalidation(layer->GetMaskLayer(), aCallback);
|
||||
}
|
||||
for (size_t i = 0; i < layer->GetAncestorMaskLayerCount(); i++) {
|
||||
Layer* maskLayer = layer->GetAncestorMaskLayerAt(i);
|
||||
NotifySubdocumentInvalidation(maskLayer, aCallback);
|
||||
}
|
||||
},
|
||||
[aCallback] (Layer* layer)
|
||||
{
|
||||
ContainerLayer* container = layer->AsContainerLayer();
|
||||
if (container) {
|
||||
aCallback(container, container->GetLocalVisibleRegion().ToUnknownRegion());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
struct LayerPropertiesBase : public LayerProperties
|
||||
@@ -346,7 +347,7 @@ struct ContainerLayerProperties : public LayerPropertiesBase
|
||||
AddTransformedRegion(result, child->GetLocalVisibleRegion().ToUnknownRegion(),
|
||||
GetTransformForInvalidation(child));
|
||||
if (aCallback) {
|
||||
NotifySubdocumentInvalidationRecursive(child, aCallback);
|
||||
NotifySubdocumentInvalidation(child, aCallback);
|
||||
} else {
|
||||
ClearInvalidations(child);
|
||||
}
|
||||
@@ -588,22 +589,20 @@ LayerProperties::CloneFrom(Layer* aRoot)
|
||||
/* static */ void
|
||||
LayerProperties::ClearInvalidations(Layer *aLayer)
|
||||
{
|
||||
aLayer->ClearInvalidRect();
|
||||
if (aLayer->GetMaskLayer()) {
|
||||
ClearInvalidations(aLayer->GetMaskLayer());
|
||||
}
|
||||
for (size_t i = 0; i < aLayer->GetAncestorMaskLayerCount(); i++) {
|
||||
ClearInvalidations(aLayer->GetAncestorMaskLayerAt(i));
|
||||
}
|
||||
ForEachNode<ForwardIterator>(
|
||||
aLayer,
|
||||
[] (Layer* layer)
|
||||
{
|
||||
layer->ClearInvalidRect();
|
||||
if (layer->GetMaskLayer()) {
|
||||
ClearInvalidations(layer->GetMaskLayer());
|
||||
}
|
||||
for (size_t i = 0; i < layer->GetAncestorMaskLayerCount(); i++) {
|
||||
ClearInvalidations(layer->GetAncestorMaskLayerAt(i));
|
||||
}
|
||||
|
||||
ContainerLayer* container = aLayer->AsContainerLayer();
|
||||
if (!container) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (Layer* child = container->GetFirstChild(); child; child = child->GetNextSibling()) {
|
||||
ClearInvalidations(child);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
nsIntRegion
|
||||
@@ -613,7 +612,7 @@ LayerPropertiesBase::ComputeDifferences(Layer* aRoot, NotifySubDocInvalidationFu
|
||||
NS_ASSERTION(aRoot, "Must have a layer tree to compare against!");
|
||||
if (mLayer != aRoot) {
|
||||
if (aCallback) {
|
||||
NotifySubdocumentInvalidationRecursive(aRoot, aCallback);
|
||||
NotifySubdocumentInvalidation(aRoot, aCallback);
|
||||
} else {
|
||||
ClearInvalidations(aRoot);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user