--- a/gfx/layers/apz/src/APZCTreeManager.cpp
+++ b/gfx/layers/apz/src/APZCTreeManager.cpp
@@ -96,16 +96,20 @@ struct APZCTreeManager::TreeBuildingStat
// is needed in addition to mNodesToDestroy because a hit testing node for a
// layer tree can be removed without the whole layer tree being removed.
std::unordered_set<uint64_t> mLayersIdsToDestroy;
// This map is populated as we place APZCs into the new tree. Its purpose is
// to facilitate re-using the same APZC for different layers that scroll
// together (and thus have the same ScrollableLayerGuid).
std::unordered_map<ScrollableLayerGuid, AsyncPanZoomController*, ScrollableLayerGuidHash> mApzcMap;
+
+ // As the tree is traversed, the top element of this stack tracks whether
+ // the parent scroll node has a perspective transform.
+ std::stack<bool> mParentHasPerspective;
};
class APZCTreeManager::CheckerboardFlushObserver : public nsIObserver {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
explicit CheckerboardFlushObserver(APZCTreeManager* aTreeManager)
@@ -322,16 +326,17 @@ APZCTreeManager::UpdateHitTestingTreeImp
if (aRoot) {
std::stack<gfx::TreeAutoIndent> indents;
std::stack<AncestorTransform> ancestorTransforms;
HitTestingTreeNode* parent = nullptr;
HitTestingTreeNode* next = nullptr;
uint64_t layersId = aRootLayerTreeId;
ancestorTransforms.push(AncestorTransform());
+ state.mParentHasPerspective.push(false);
state.mLayersIdsToDestroy.erase(aRootLayerTreeId);
mApzcTreeLog << "[start]\n";
mTreeLock.AssertCurrentThreadOwns();
ForEachNode<ReverseIterator>(aRoot,
[&](ScrollNode aLayerMetrics)
@@ -371,24 +376,26 @@ APZCTreeManager::UpdateHitTestingTreeImp
if (Maybe<uint64_t> newLayersId = aLayerMetrics.GetReferentId()) {
layersId = *newLayersId;
// Mark that this layer tree is being used
state.mLayersIdsToDestroy.erase(layersId);
}
indents.push(gfx::TreeAutoIndent(mApzcTreeLog));
+ state.mParentHasPerspective.push(aLayerMetrics.TransformIsPerspective());
},
[&](ScrollNode aLayerMetrics)
{
next = parent;
parent = parent->GetParent();
layersId = next->GetLayersId();
ancestorTransforms.pop();
indents.pop();
+ state.mParentHasPerspective.pop();
});
mApzcTreeLog << "[end]\n";
}
// We do not support tree structures where the root node has siblings.
MOZ_ASSERT(!(mRootNode && mRootNode->GetPrevSibling()));
@@ -739,28 +746,32 @@ APZCTreeManager::PrepareNodeForLayer(con
needsApzc = false;
}
const LayerTreeState* state = CompositorBridgeParent::GetIndirectShadowTree(aLayersId);
if (!(state && state->mController.get())) {
needsApzc = false;
}
+ bool parentHasPerspective = aState.mParentHasPerspective.top();
+
RefPtr<HitTestingTreeNode> node = nullptr;
if (!needsApzc) {
// Note: if layer properties must be propagated to nodes, RecvUpdate in
// LayerTransactionParent.cpp must ensure that APZ will be notified
// when those properties change.
node = RecycleOrCreateNode(aState, nullptr, aLayersId);
AttachNodeToTree(node, aParent, aNextSibling);
node->SetHitTestData(
GetEventRegions(aLayer),
aLayer.GetVisibleRegion(),
aLayer.GetTransformTyped(),
- aLayer.GetClipRect() ? Some(ParentLayerIntRegion(*aLayer.GetClipRect())) : Nothing(),
+ (!parentHasPerspective && aLayer.GetClipRect())
+ ? Some(ParentLayerIntRegion(*aLayer.GetClipRect()))
+ : Nothing(),
GetEventRegionsOverride(aParent, aLayer));
node->SetScrollbarData(aLayer.GetScrollbarTargetContainerId(),
aLayer.GetScrollbarAnimationId(),
aLayer.GetScrollThumbData(),
aLayer.GetScrollbarContainerDirection());
node->SetFixedPosData(aLayer.GetFixedPositionScrollContainerId());
return node;
}
@@ -857,22 +868,24 @@ APZCTreeManager::PrepareNodeForLayer(con
apzc->NotifyLayersUpdated(aLayer.Metadata(), aState.mIsFirstPaint,
aLayersId == aState.mOriginatingLayersId);
// Since this is the first time we are encountering an APZC with this guid,
// the node holding it must be the primary holder. It may be newly-created
// or not, depending on whether it went through the newApzc branch above.
MOZ_ASSERT(node->IsPrimaryHolder() && node->GetApzc() && node->GetApzc()->Matches(guid));
- ParentLayerIntRegion clipRegion = ComputeClipRegion(state->mController, aLayer);
+ Maybe<ParentLayerIntRegion> clipRegion = parentHasPerspective
+ ? Nothing()
+ : Some(ComputeClipRegion(state->mController, aLayer));
node->SetHitTestData(
GetEventRegions(aLayer),
aLayer.GetVisibleRegion(),
aLayer.GetTransformTyped(),
- Some(clipRegion),
+ clipRegion,
GetEventRegionsOverride(aParent, aLayer));
apzc->SetAncestorTransform(aAncestorTransform);
PrintAPZCInfo(aLayer, apzc);
// Bind the APZC instance into the tree of APZCs
AttachNodeToTree(node, aParent, aNextSibling);
@@ -947,22 +960,24 @@ APZCTreeManager::PrepareNodeForLayer(con
if (!aAncestorTransform.mContainsPerspectiveTransform &&
!apzc->AncestorTransformContainsPerspective()) {
MOZ_ASSERT(false, "Two layers that scroll together have different ancestor transforms");
} else if (!aAncestorTransform.mContainsPerspectiveTransform) {
apzc->SetAncestorTransform(aAncestorTransform);
}
}
- ParentLayerIntRegion clipRegion = ComputeClipRegion(state->mController, aLayer);
+ Maybe<ParentLayerIntRegion> clipRegion = parentHasPerspective
+ ? Nothing()
+ : Some(ComputeClipRegion(state->mController, aLayer));
node->SetHitTestData(
GetEventRegions(aLayer),
aLayer.GetVisibleRegion(),
aLayer.GetTransformTyped(),
- Some(clipRegion),
+ clipRegion,
GetEventRegionsOverride(aParent, aLayer));
}
// Note: if layer properties must be propagated to nodes, RecvUpdate in
// LayerTransactionParent.cpp must ensure that APZ will be notified
// when those properties change.
node->SetScrollbarData(aLayer.GetScrollbarTargetContainerId(),
aLayer.GetScrollbarAnimationId(),