mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 19:04:45 +00:00
Bug 1227233: Increase scope of TreeTraversal.h to by-value traversal r=botond
MozReview-Commit-ID: LOw1k792T10 --HG-- extra : rebase_source : a81ac06686bc21ed69693a3a80551e0648a8299a
This commit is contained in:
parent
8f2b2148c6
commit
16d7a2302e
@ -643,7 +643,10 @@ public:
|
||||
}
|
||||
|
||||
void IncreaseIndent() { ++mDepth; }
|
||||
void DecreaseIndent() { --mDepth; }
|
||||
void DecreaseIndent() {
|
||||
MOZ_ASSERT(mDepth > 0);
|
||||
--mDepth;
|
||||
}
|
||||
|
||||
void ConditionOnPrefFunction(bool(*aPrefFunction)()) {
|
||||
mConditionedOnPref = true;
|
||||
@ -681,6 +684,14 @@ public:
|
||||
explicit TreeAutoIndent(TreeLog& aTreeLog) : mTreeLog(aTreeLog) {
|
||||
mTreeLog.IncreaseIndent();
|
||||
}
|
||||
|
||||
TreeAutoIndent(const TreeAutoIndent& aTreeAutoIndent) :
|
||||
TreeAutoIndent(aTreeAutoIndent.mTreeLog) {
|
||||
mTreeLog.IncreaseIndent();
|
||||
}
|
||||
|
||||
TreeAutoIndent& operator=(const TreeAutoIndent& aTreeAutoIndent) = delete;
|
||||
|
||||
~TreeAutoIndent() {
|
||||
mTreeLog.DecreaseIndent();
|
||||
}
|
||||
|
@ -80,24 +80,20 @@ LayerManager::GetRootScrollableLayerId()
|
||||
return FrameMetrics::NULL_SCROLL_ID;
|
||||
}
|
||||
|
||||
nsTArray<LayerMetricsWrapper> queue = { LayerMetricsWrapper(mRoot) };
|
||||
while (queue.Length()) {
|
||||
LayerMetricsWrapper layer = queue[0];
|
||||
queue.RemoveElementAt(0);
|
||||
LayerMetricsWrapper layerMetricsRoot = LayerMetricsWrapper(mRoot);
|
||||
|
||||
const FrameMetrics& frameMetrics = layer.Metrics();
|
||||
if (frameMetrics.IsScrollable()) {
|
||||
return frameMetrics.GetScrollId();
|
||||
}
|
||||
LayerMetricsWrapper rootScrollableLayerMetrics =
|
||||
BreadthFirstSearch<ForwardIterator>(
|
||||
layerMetricsRoot,
|
||||
[](LayerMetricsWrapper aLayerMetrics)
|
||||
{
|
||||
return aLayerMetrics.Metrics().IsScrollable();
|
||||
}
|
||||
);
|
||||
|
||||
LayerMetricsWrapper child = layer.GetFirstChild();
|
||||
while (child) {
|
||||
queue.AppendElement(child);
|
||||
child = child.GetNextSibling();
|
||||
}
|
||||
}
|
||||
|
||||
return FrameMetrics::NULL_SCROLL_ID;
|
||||
return rootScrollableLayerMetrics.IsValid() ?
|
||||
rootScrollableLayerMetrics.Metrics().GetScrollId() :
|
||||
FrameMetrics::NULL_SCROLL_ID;
|
||||
}
|
||||
|
||||
void
|
||||
@ -159,23 +155,14 @@ LayerManager::GetRootContentLayer()
|
||||
return LayerMetricsWrapper();
|
||||
}
|
||||
|
||||
nsTArray<Layer*> queue = { mRoot };
|
||||
while (!queue.IsEmpty()) {
|
||||
Layer* layer = queue[0];
|
||||
queue.RemoveElementAt(0);
|
||||
LayerMetricsWrapper root(mRoot);
|
||||
|
||||
for (uint32_t i = 0; i < layer->GetScrollMetadataCount(); i++) {
|
||||
if (layer->GetFrameMetrics(i).IsRootContent()) {
|
||||
return LayerMetricsWrapper(layer, i);
|
||||
return BreadthFirstSearch<ForwardIterator>(root,
|
||||
[](LayerMetricsWrapper aLayerMetrics)
|
||||
{
|
||||
return aLayerMetrics.Metrics().IsRootContent();
|
||||
}
|
||||
}
|
||||
|
||||
for (Layer* child = layer->GetFirstChild(); child; child = child->GetNextSibling()) {
|
||||
queue.AppendElement(child);
|
||||
}
|
||||
}
|
||||
|
||||
return LayerMetricsWrapper();
|
||||
);
|
||||
}
|
||||
|
||||
already_AddRefed<DrawTarget>
|
||||
|
@ -34,25 +34,41 @@ enum class TraversalFlag { Skip, Continue, Abort };
|
||||
class ForwardIterator
|
||||
{
|
||||
public:
|
||||
template <typename Node>
|
||||
static Node* FirstChild(Node* n) {
|
||||
return n->GetFirstChild();
|
||||
}
|
||||
template <typename Node>
|
||||
static Node* NextSibling(Node* n) {
|
||||
return n->GetNextSibling();
|
||||
}
|
||||
template <typename Node>
|
||||
static Node* FirstChild(Node* n) {
|
||||
return n->GetFirstChild();
|
||||
static Node FirstChild(Node n) {
|
||||
return n.GetFirstChild();
|
||||
}
|
||||
template <typename Node>
|
||||
static Node NextSibling(Node n) {
|
||||
return n.GetNextSibling();
|
||||
}
|
||||
};
|
||||
class ReverseIterator
|
||||
{
|
||||
public:
|
||||
template <typename Node>
|
||||
static Node* FirstChild(Node* n) {
|
||||
return n->GetLastChild();
|
||||
}
|
||||
template <typename Node>
|
||||
static Node* NextSibling(Node* n) {
|
||||
return n->GetPrevSibling();
|
||||
}
|
||||
template <typename Node>
|
||||
static Node* FirstChild(Node* n) {
|
||||
return n->GetLastChild();
|
||||
static Node FirstChild(Node n) {
|
||||
return n.GetLastChild();
|
||||
}
|
||||
template <typename Node>
|
||||
static Node NextSibling(Node n) {
|
||||
return n.GetPrevSibling();
|
||||
}
|
||||
};
|
||||
|
||||
@ -65,13 +81,13 @@ class ReverseIterator
|
||||
* is not performed.
|
||||
*
|
||||
* |Iterator| should have static methods named NextSibling() and FirstChild()
|
||||
* that accept an argument of type Node*. For convenience, classes
|
||||
* that accept an argument of type Node. For convenience, classes
|
||||
* |ForwardIterator| and |ReverseIterator| are provided which implement these
|
||||
* methods as GetNextSibling()/GetFirstChild() and GetPrevSibling()/GetLastChild(),
|
||||
* respectively.
|
||||
*/
|
||||
template <typename Iterator, typename Node, typename PreAction, typename PostAction>
|
||||
static auto ForEachNode(Node* aRoot, const PreAction& aPreAction, const PostAction& aPostAction) ->
|
||||
static auto ForEachNode(Node aRoot, const PreAction& aPreAction, const PostAction& aPostAction) ->
|
||||
typename EnableIf<IsSame<decltype(aPreAction(aRoot)), TraversalFlag>::value &&
|
||||
IsSame<decltype(aPostAction(aRoot)),TraversalFlag>::value, bool>::Type
|
||||
{
|
||||
@ -86,7 +102,7 @@ typename EnableIf<IsSame<decltype(aPreAction(aRoot)), TraversalFlag>::value &&
|
||||
}
|
||||
|
||||
if (result == TraversalFlag::Continue) {
|
||||
for (Node* child = Iterator::FirstChild(aRoot);
|
||||
for (Node child = Iterator::FirstChild(aRoot);
|
||||
child;
|
||||
child = Iterator::NextSibling(child)) {
|
||||
bool abort = ForEachNode<Iterator>(child, aPreAction, aPostAction);
|
||||
@ -110,7 +126,7 @@ typename EnableIf<IsSame<decltype(aPreAction(aRoot)), TraversalFlag>::value &&
|
||||
* |aPreAction| before traversal of children and |aPostAction| after.
|
||||
*/
|
||||
template <typename Iterator, typename Node, typename PreAction, typename PostAction>
|
||||
static auto ForEachNode(Node* aRoot, const PreAction& aPreAction, const PostAction& aPostAction) ->
|
||||
static auto ForEachNode(Node aRoot, const PreAction& aPreAction, const PostAction& aPostAction) ->
|
||||
typename EnableIf<IsSame<decltype(aPreAction(aRoot)), void>::value &&
|
||||
IsSame<decltype(aPostAction(aRoot)),void>::value, void>::Type
|
||||
{
|
||||
@ -120,7 +136,7 @@ typename EnableIf<IsSame<decltype(aPreAction(aRoot)), void>::value &&
|
||||
|
||||
aPreAction(aRoot);
|
||||
|
||||
for (Node* child = Iterator::FirstChild(aRoot);
|
||||
for (Node child = Iterator::FirstChild(aRoot);
|
||||
child;
|
||||
child = Iterator::NextSibling(child)) {
|
||||
ForEachNode<Iterator>(child, aPreAction, aPostAction);
|
||||
@ -133,40 +149,40 @@ typename EnableIf<IsSame<decltype(aPreAction(aRoot)), void>::value &&
|
||||
* ForEachNode pre-order traversal, using TraversalFlag.
|
||||
*/
|
||||
template <typename Iterator, typename Node, typename PreAction>
|
||||
auto ForEachNode(Node* aRoot, const PreAction& aPreAction) ->
|
||||
auto ForEachNode(Node aRoot, const PreAction& aPreAction) ->
|
||||
typename EnableIf<IsSame<decltype(aPreAction(aRoot)), TraversalFlag>::value, bool>::Type
|
||||
{
|
||||
return ForEachNode<Iterator>(aRoot, aPreAction, [](Node* aNode){ return TraversalFlag::Continue; });
|
||||
return ForEachNode<Iterator>(aRoot, aPreAction, [](Node aNode){ return TraversalFlag::Continue; });
|
||||
}
|
||||
|
||||
/*
|
||||
* ForEachNode pre-order, not using TraversalFlag.
|
||||
*/
|
||||
template <typename Iterator, typename Node, typename PreAction>
|
||||
auto ForEachNode(Node* aRoot, const PreAction& aPreAction) ->
|
||||
auto ForEachNode(Node aRoot, const PreAction& aPreAction) ->
|
||||
typename EnableIf<IsSame<decltype(aPreAction(aRoot)), void>::value, void>::Type
|
||||
{
|
||||
ForEachNode<Iterator>(aRoot, aPreAction, [](Node* aNode){});
|
||||
ForEachNode<Iterator>(aRoot, aPreAction, [](Node aNode){});
|
||||
}
|
||||
|
||||
/*
|
||||
* ForEachNode post-order traversal, using TraversalFlag.
|
||||
*/
|
||||
template <typename Iterator, typename Node, typename PostAction>
|
||||
auto ForEachNodePostOrder(Node* aRoot, const PostAction& aPostAction) ->
|
||||
auto ForEachNodePostOrder(Node aRoot, const PostAction& aPostAction) ->
|
||||
typename EnableIf<IsSame<decltype(aPostAction(aRoot)), TraversalFlag>::value, bool>::Type
|
||||
{
|
||||
return ForEachNode<Iterator>(aRoot, [](Node* aNode){ return TraversalFlag::Continue; }, aPostAction);
|
||||
return ForEachNode<Iterator>(aRoot, [](Node aNode){ return TraversalFlag::Continue; }, aPostAction);
|
||||
}
|
||||
|
||||
/*
|
||||
* ForEachNode post-order, not using TraversalFlag.
|
||||
*/
|
||||
template <typename Iterator, typename Node, typename PostAction>
|
||||
auto ForEachNodePostOrder(Node* aRoot, const PostAction& aPostAction) ->
|
||||
auto ForEachNodePostOrder(Node aRoot, const PostAction& aPostAction) ->
|
||||
typename EnableIf<IsSame<decltype(aPostAction(aRoot)), void>::value, void>::Type
|
||||
{
|
||||
ForEachNode<Iterator>(aRoot, [](Node* aNode){}, aPostAction);
|
||||
ForEachNode<Iterator>(aRoot, [](Node aNode){}, aPostAction);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -174,33 +190,35 @@ typename EnableIf<IsSame<decltype(aPostAction(aRoot)), void>::value, void>::Type
|
||||
* first visited node that satisfies |aCondition|, or nullptr if no such node
|
||||
* was found.
|
||||
*
|
||||
* See ForEachNode() for the requirements on |Iterator| and |Node|
|
||||
* |Iterator| and |Node| have all the same requirements seen in ForEachNode()'s
|
||||
* definition, but in addition to those, |Node| must be able to express a null
|
||||
* value, returned from Node()
|
||||
*/
|
||||
template <typename Iterator, typename Node, typename Condition>
|
||||
Node* BreadthFirstSearch(Node* aRoot, const Condition& aCondition)
|
||||
Node BreadthFirstSearch(Node aRoot, const Condition& aCondition)
|
||||
{
|
||||
if (!aRoot) {
|
||||
return nullptr;
|
||||
return Node();
|
||||
}
|
||||
|
||||
std::queue<Node*> queue;
|
||||
std::queue<Node> queue;
|
||||
queue.push(aRoot);
|
||||
while (!queue.empty()) {
|
||||
Node* node = queue.front();
|
||||
Node node = queue.front();
|
||||
queue.pop();
|
||||
|
||||
if (aCondition(node)) {
|
||||
return node;
|
||||
}
|
||||
|
||||
for (Node* child = Iterator::FirstChild(node);
|
||||
for (Node child = Iterator::FirstChild(node);
|
||||
child;
|
||||
child = Iterator::NextSibling(child)) {
|
||||
queue.push(child);
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
return Node();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -208,15 +226,17 @@ Node* BreadthFirstSearch(Node* aRoot, const Condition& aCondition)
|
||||
* return the first visited node that satisfies |aCondition|, or nullptr
|
||||
* if no such node was found.
|
||||
*
|
||||
* See ForEachNode() for the requirements on |Iterator| and |Node|
|
||||
* |Iterator| and |Node| have all the same requirements seen in ForEachNode()'s
|
||||
* definition, but in addition to those, |Node| must be able to express a null
|
||||
* value, returned from Node().
|
||||
*/
|
||||
template <typename Iterator, typename Node, typename Condition>
|
||||
Node* DepthFirstSearch(Node* aRoot, const Condition& aCondition)
|
||||
Node DepthFirstSearch(Node aRoot, const Condition& aCondition)
|
||||
{
|
||||
Node* result = nullptr;
|
||||
Node result = Node();
|
||||
|
||||
ForEachNode<Iterator>(aRoot,
|
||||
[&aCondition, &result](Node* aNode)
|
||||
[&aCondition, &result](Node aNode)
|
||||
{
|
||||
if (aCondition(aNode)) {
|
||||
result = aNode;
|
||||
@ -232,15 +252,17 @@ Node* DepthFirstSearch(Node* aRoot, const Condition& aCondition)
|
||||
/*
|
||||
* Perform a post-order, depth-first search starting at aRoot.
|
||||
*
|
||||
* See ForEachNode() for the requirements on |Iterator| and |Node|
|
||||
* |Iterator| and |Node| have all the same requirements seen in ForEachNode()'s
|
||||
* definition, but in addition to those, |Node| must be able to express a null
|
||||
* value, returned from Node().
|
||||
*/
|
||||
template <typename Iterator, typename Node, typename Condition>
|
||||
Node* DepthFirstSearchPostOrder(Node* aRoot, const Condition& aCondition)
|
||||
Node DepthFirstSearchPostOrder(Node aRoot, const Condition& aCondition)
|
||||
{
|
||||
Node* result = nullptr;
|
||||
Node result = Node();
|
||||
|
||||
ForEachNodePostOrder<Iterator>(aRoot,
|
||||
[&aCondition, &result](Node* aNode)
|
||||
[&aCondition, &result](Node aNode)
|
||||
{
|
||||
if (aCondition(aNode)) {
|
||||
result = aNode;
|
||||
|
@ -180,12 +180,65 @@ APZCTreeManager::UpdateHitTestingTree(CompositorBridgeParent* aCompositor,
|
||||
mRootNode = nullptr;
|
||||
|
||||
if (aRoot) {
|
||||
std::stack<gfx::TreeAutoIndent> indents;
|
||||
std::stack<gfx::Matrix4x4> ancestorTransforms;
|
||||
HitTestingTreeNode* parent = nullptr;
|
||||
HitTestingTreeNode* next = nullptr;
|
||||
|
||||
// aCompositor is null in gtest scenarios
|
||||
uint64_t layersId = aCompositor ? aCompositor->RootLayerTreeId() : 0;
|
||||
ancestorTransforms.push(Matrix4x4());
|
||||
|
||||
mApzcTreeLog << "[start]\n";
|
||||
LayerMetricsWrapper root(aRoot);
|
||||
UpdateHitTestingTree(state, root,
|
||||
// aCompositor is null in gtest scenarios
|
||||
aCompositor ? aCompositor->RootLayerTreeId() : 0,
|
||||
Matrix4x4(), nullptr, nullptr);
|
||||
mTreeLock.AssertCurrentThreadOwns();
|
||||
|
||||
ForEachNode<ReverseIterator>(root,
|
||||
[&](LayerMetricsWrapper aLayerMetrics)
|
||||
{
|
||||
mApzcTreeLog << aLayerMetrics.Name() << '\t';
|
||||
|
||||
HitTestingTreeNode* node = PrepareNodeForLayer(aLayerMetrics,
|
||||
aLayerMetrics.Metrics(), layersId, ancestorTransforms.top(),
|
||||
parent, next, state);
|
||||
MOZ_ASSERT(node);
|
||||
AsyncPanZoomController* apzc = node->GetApzc();
|
||||
aLayerMetrics.SetApzc(apzc);
|
||||
|
||||
mApzcTreeLog << '\n';
|
||||
|
||||
// Accumulate the CSS transform between layers that have an APZC.
|
||||
// In the terminology of the big comment above APZCTreeManager::GetScreenToApzcTransform, if
|
||||
// we are at layer M, then aAncestorTransform is NC * OC * PC, and we left-multiply MC and
|
||||
// compute ancestorTransform to be MC * NC * OC * PC. This gets passed down as the ancestor
|
||||
// transform to layer L when we recurse into the children below. If we are at a layer
|
||||
// with an APZC, such as P, then we reset the ancestorTransform to just PC, to start
|
||||
// the new accumulation as we go down.
|
||||
// If a transform is a perspective transform, it's ignored for this purpose
|
||||
// (see bug 1168263).
|
||||
Matrix4x4 currentTransform = aLayerMetrics.TransformIsPerspective() ? Matrix4x4() : aLayerMetrics.GetTransform();
|
||||
if (!apzc) {
|
||||
currentTransform = currentTransform * ancestorTransforms.top();
|
||||
}
|
||||
ancestorTransforms.push(currentTransform);
|
||||
|
||||
// Note that |node| at this point will not have any children, otherwise we
|
||||
// we would have to set next to node->GetFirstChild().
|
||||
MOZ_ASSERT(!node->GetFirstChild());
|
||||
parent = node;
|
||||
next = nullptr;
|
||||
layersId = (aLayerMetrics.AsRefLayer() ? aLayerMetrics.AsRefLayer()->GetReferentId() : layersId);
|
||||
indents.push(gfx::TreeAutoIndent(mApzcTreeLog));
|
||||
},
|
||||
[&](LayerMetricsWrapper aLayerMetrics)
|
||||
{
|
||||
next = parent;
|
||||
parent = parent->GetParent();
|
||||
layersId = next->GetLayersId();
|
||||
ancestorTransforms.pop();
|
||||
indents.pop();
|
||||
});
|
||||
|
||||
mApzcTreeLog << "[end]\n";
|
||||
}
|
||||
|
||||
@ -563,57 +616,6 @@ APZCTreeManager::PrepareNodeForLayer(const LayerMetricsWrapper& aLayer,
|
||||
return node;
|
||||
}
|
||||
|
||||
HitTestingTreeNode*
|
||||
APZCTreeManager::UpdateHitTestingTree(TreeBuildingState& aState,
|
||||
const LayerMetricsWrapper& aLayer,
|
||||
uint64_t aLayersId,
|
||||
const gfx::Matrix4x4& aAncestorTransform,
|
||||
HitTestingTreeNode* aParent,
|
||||
HitTestingTreeNode* aNextSibling)
|
||||
{
|
||||
mTreeLock.AssertCurrentThreadOwns();
|
||||
|
||||
mApzcTreeLog << aLayer.Name() << '\t';
|
||||
|
||||
HitTestingTreeNode* node = PrepareNodeForLayer(aLayer,
|
||||
aLayer.Metrics(), aLayersId, aAncestorTransform,
|
||||
aParent, aNextSibling, aState);
|
||||
MOZ_ASSERT(node);
|
||||
AsyncPanZoomController* apzc = node->GetApzc();
|
||||
aLayer.SetApzc(apzc);
|
||||
|
||||
mApzcTreeLog << '\n';
|
||||
|
||||
// Accumulate the CSS transform between layers that have an APZC.
|
||||
// In the terminology of the big comment above APZCTreeManager::GetScreenToApzcTransform, if
|
||||
// we are at layer M, then aAncestorTransform is NC * OC * PC, and we left-multiply MC and
|
||||
// compute ancestorTransform to be MC * NC * OC * PC. This gets passed down as the ancestor
|
||||
// transform to layer L when we recurse into the children below. If we are at a layer
|
||||
// with an APZC, such as P, then we reset the ancestorTransform to just PC, to start
|
||||
// the new accumulation as we go down.
|
||||
// If a transform is a perspective transform, it's ignored for this purpose
|
||||
// (see bug 1168263).
|
||||
Matrix4x4 ancestorTransform = aLayer.TransformIsPerspective() ? Matrix4x4() : aLayer.GetTransform();
|
||||
if (!apzc) {
|
||||
ancestorTransform = ancestorTransform * aAncestorTransform;
|
||||
}
|
||||
|
||||
// Note that |node| at this point will not have any children, otherwise we
|
||||
// we would have to set next to node->GetFirstChild().
|
||||
MOZ_ASSERT(!node->GetFirstChild());
|
||||
aParent = node;
|
||||
HitTestingTreeNode* next = nullptr;
|
||||
|
||||
uint64_t childLayersId = (aLayer.AsRefLayer() ? aLayer.AsRefLayer()->GetReferentId() : aLayersId);
|
||||
for (LayerMetricsWrapper child = aLayer.GetLastChild(); child; child = child.GetPrevSibling()) {
|
||||
gfx::TreeAutoIndent indent(mApzcTreeLog);
|
||||
next = UpdateHitTestingTree(aState, child, childLayersId,
|
||||
ancestorTransform, aParent, next);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
template<typename PanGestureOrScrollWheelInput>
|
||||
static bool
|
||||
WillHandleInput(const PanGestureOrScrollWheelInput& aPanInput)
|
||||
|
@ -474,34 +474,6 @@ private:
|
||||
HitTestingTreeNode* aNextSibling,
|
||||
TreeBuildingState& aState);
|
||||
|
||||
/**
|
||||
* Recursive helper function to build the hit-testing tree. See documentation
|
||||
* in HitTestingTreeNode.h for more details on the shape of the tree.
|
||||
* This function walks the layer tree backwards through siblings and
|
||||
* constructs the hit-testing tree also as a last-child-prev-sibling tree
|
||||
* because that simplifies the hit detection code.
|
||||
*
|
||||
* @param aState The current tree building state.
|
||||
* @param aLayer The (layer, metrics) pair which is the current position in
|
||||
* the recursive walk of the layer tree. This call builds a
|
||||
* hit-testing subtree corresponding to the layer subtree rooted
|
||||
* at aLayer.
|
||||
* @param aLayersId The layers id of the layer in aLayer.
|
||||
* @param aAncestorTransform The accumulated CSS transforms of all the
|
||||
* layers from aLayer up (via the parent chain)
|
||||
* to the next APZC-bearing layer.
|
||||
* @param aParent The parent of any node built at this level.
|
||||
* @param aNextSibling The next sibling of any node built at this level.
|
||||
* @return The HitTestingTreeNode created at this level. This will always
|
||||
* be non-null.
|
||||
*/
|
||||
HitTestingTreeNode* UpdateHitTestingTree(TreeBuildingState& aState,
|
||||
const LayerMetricsWrapper& aLayer,
|
||||
uint64_t aLayersId,
|
||||
const gfx::Matrix4x4& aAncestorTransform,
|
||||
HitTestingTreeNode* aParent,
|
||||
HitTestingTreeNode* aNextSibling);
|
||||
|
||||
void PrintAPZCInfo(const LayerMetricsWrapper& aLayer,
|
||||
const AsyncPanZoomController* apzc);
|
||||
|
||||
|
@ -768,15 +768,16 @@ static bool
|
||||
SampleAPZAnimations(const LayerMetricsWrapper& aLayer, TimeStamp aSampleTime)
|
||||
{
|
||||
bool activeAnimations = false;
|
||||
for (LayerMetricsWrapper child = aLayer.GetFirstChild(); child;
|
||||
child = child.GetNextSibling()) {
|
||||
activeAnimations |= SampleAPZAnimations(child, aSampleTime);
|
||||
}
|
||||
|
||||
if (AsyncPanZoomController* apzc = aLayer.GetApzc()) {
|
||||
apzc->ReportCheckerboard(aSampleTime);
|
||||
activeAnimations |= apzc->AdvanceAnimations(aSampleTime);
|
||||
}
|
||||
ForEachNodePostOrder<ForwardIterator>(aLayer,
|
||||
[&activeAnimations, &aSampleTime](LayerMetricsWrapper aLayerMetrics)
|
||||
{
|
||||
if (AsyncPanZoomController* apzc = aLayerMetrics.GetApzc()) {
|
||||
apzc->ReportCheckerboard(aSampleTime);
|
||||
activeAnimations |= apzc->AdvanceAnimations(aSampleTime);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
return activeAnimations;
|
||||
}
|
||||
@ -1326,37 +1327,14 @@ ApplyAsyncTransformToScrollbarForContent(Layer* aScrollbar,
|
||||
SetShadowTransform(aScrollbar, transform);
|
||||
}
|
||||
|
||||
static LayerMetricsWrapper
|
||||
FindScrolledLayerRecursive(Layer* aScrollbar, const LayerMetricsWrapper& aSubtreeRoot)
|
||||
{
|
||||
if (LayerIsScrollbarTarget(aSubtreeRoot, aScrollbar)) {
|
||||
return aSubtreeRoot;
|
||||
}
|
||||
|
||||
for (LayerMetricsWrapper child = aSubtreeRoot.GetFirstChild();
|
||||
child;
|
||||
child = child.GetNextSibling())
|
||||
{
|
||||
// Do not recurse into RefLayers, since our initial aSubtreeRoot is the
|
||||
// root (or RefLayer root) of a single layer space to search.
|
||||
if (child.AsRefLayer()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
LayerMetricsWrapper target = FindScrolledLayerRecursive(aScrollbar, child);
|
||||
if (target) {
|
||||
return target;
|
||||
}
|
||||
}
|
||||
return LayerMetricsWrapper();
|
||||
}
|
||||
|
||||
static LayerMetricsWrapper
|
||||
FindScrolledLayerForScrollbar(Layer* aScrollbar, bool* aOutIsAncestor)
|
||||
{
|
||||
// First check if the scrolled layer is an ancestor of the scrollbar layer.
|
||||
LayerMetricsWrapper root(aScrollbar->Manager()->GetRoot());
|
||||
LayerMetricsWrapper prevAncestor(aScrollbar);
|
||||
LayerMetricsWrapper scrolledLayer;
|
||||
|
||||
for (LayerMetricsWrapper ancestor(aScrollbar); ancestor; ancestor = ancestor.GetParent()) {
|
||||
// Don't walk into remote layer trees; the scrollbar will always be in
|
||||
// the same layer space.
|
||||
@ -1373,7 +1351,23 @@ FindScrolledLayerForScrollbar(Layer* aScrollbar, bool* aOutIsAncestor)
|
||||
}
|
||||
|
||||
// Search the entire layer space of the scrollbar.
|
||||
return FindScrolledLayerRecursive(aScrollbar, root);
|
||||
ForEachNode<ForwardIterator>(
|
||||
root,
|
||||
[&root, &scrolledLayer, &aScrollbar](LayerMetricsWrapper aLayerMetrics)
|
||||
{
|
||||
// Do not recurse into RefLayers, since our initial aSubtreeRoot is the
|
||||
// root (or RefLayer root) of a single layer space to search.
|
||||
if (root != aLayerMetrics && aLayerMetrics.AsRefLayer()) {
|
||||
return TraversalFlag::Skip;
|
||||
}
|
||||
if (LayerIsScrollbarTarget(aLayerMetrics, aScrollbar)) {
|
||||
scrolledLayer = aLayerMetrics;
|
||||
return TraversalFlag::Abort;
|
||||
}
|
||||
return TraversalFlag::Continue;
|
||||
}
|
||||
);
|
||||
return scrolledLayer;
|
||||
}
|
||||
|
||||
void
|
||||
|
Loading…
Reference in New Issue
Block a user