Skip to content

Commit

Permalink
Bug 1650868 - Make the async zoom containment checks subtree-specific…
Browse files Browse the repository at this point in the history
…. r=botond

Differential Revision: https://phabricator.services.mozilla.com/D82438
  • Loading branch information
staktrace committed Jul 7, 2020
1 parent c65f6e0 commit bf0c5bb
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 24 deletions.
46 changes: 26 additions & 20 deletions gfx/layers/apz/src/APZCTreeManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,6 @@ APZCTreeManager::APZCTreeManager(LayersId aRootLayersId)
mSampler(nullptr),
mUpdater(nullptr),
mTreeLock("APZCTreeLock"),
mUsingAsyncZoomContainer(false),
mMapLock("APZCMapLock"),
mRetainedTouchIdentifier(-1),
mInScrollbarTouchDrag(false),
Expand Down Expand Up @@ -405,10 +404,10 @@ APZCTreeManager::UpdateHitTestingTreeImpl(const ScrollNode& aRoot,
state.mNodesToDestroy.AppendElement(aNode);
});
mRootNode = nullptr;
mUsingAsyncZoomContainer = false;
mAsyncZoomContainerSubtree = Nothing();
int asyncZoomContainerNestingDepth = 0;
bool haveMultipleAsyncZoomContainers = false;
bool haveRootContentOutsideAsyncZoomContainer = false;
bool haveNestedAsyncZoomContainers = false;
nsTArray<LayersId> subtreesWithRootContentOutsideAsyncZoomContainer;

if (aRoot) {
std::unordered_set<LayersId, LayersId::HashFn> seenLayersIds;
Expand All @@ -431,10 +430,10 @@ APZCTreeManager::UpdateHitTestingTreeImpl(const ScrollNode& aRoot,
mApzcTreeLog << aLayerMetrics.Name() << '\t';

if (aLayerMetrics.IsAsyncZoomContainer()) {
if (mUsingAsyncZoomContainer) {
haveMultipleAsyncZoomContainers = true;
if (asyncZoomContainerNestingDepth > 0) {
haveNestedAsyncZoomContainers = true;
}
mUsingAsyncZoomContainer = true;
mAsyncZoomContainerSubtree = Some(layersId);
++asyncZoomContainerNestingDepth;
}

Expand All @@ -453,7 +452,8 @@ APZCTreeManager::UpdateHitTestingTreeImpl(const ScrollNode& aRoot,
// metadata to be on the same node as the async zoom container.
if (aLayerMetrics.Metrics().IsRootContent() &&
asyncZoomContainerNestingDepth == 0) {
haveRootContentOutsideAsyncZoomContainer = true;
subtreesWithRootContentOutsideAsyncZoomContainer.AppendElement(
layersId);
}

HitTestingTreeNode* node = PrepareNodeForLayer(
Expand Down Expand Up @@ -561,15 +561,17 @@ APZCTreeManager::UpdateHitTestingTreeImpl(const ScrollNode& aRoot,
mApzcTreeLog << "[end]\n";

MOZ_ASSERT(
!mUsingAsyncZoomContainer || !haveRootContentOutsideAsyncZoomContainer,
!mAsyncZoomContainerSubtree ||
!subtreesWithRootContentOutsideAsyncZoomContainer.Contains(
*mAsyncZoomContainerSubtree),
"If there is an async zoom container, all scroll nodes with root "
"content scroll metadata should be inside it");
// TODO(bug 1534459): Avoid multiple async zoom containers. They
// TODO(bug 1534459): Avoid nested async zoom containers. They
// can't currently occur in production code, but that will become
// possible with either OOP iframes or desktop zooming (due to
// RDM), and will need to be guarded against.
// MOZ_ASSERT(!haveMultipleAsyncZoomContainers,
// "Should only have one async zoom container");
// MOZ_ASSERT(!haveNestedAsyncZoomContainers,
// "Should not have nested async zoom container");

// If we have perspective transforms deferred to children, do another
// walk of the tree and actually apply them to the children.
Expand Down Expand Up @@ -977,11 +979,12 @@ bool APZCTreeManager::AdvanceAnimationsInternal(
// is only called for layers which actually have scrollable metrics and an APZC.
template <class ScrollNode>
Maybe<ParentLayerIntRegion> APZCTreeManager::ComputeClipRegion(
const ScrollNode& aLayer) {
const LayersId& aLayersId, const ScrollNode& aLayer) {
Maybe<ParentLayerIntRegion> clipRegion;
if (aLayer.GetClipRect()) {
clipRegion.emplace(*aLayer.GetClipRect());
} else if (aLayer.Metrics().IsRootContent() && mUsingAsyncZoomContainer) {
} else if (aLayer.Metrics().IsRootContent() &&
mAsyncZoomContainerSubtree == Some(aLayersId)) {
// If we are using containerless scrolling, part of the root content
// layers' async transform has been lifted to the async zoom container
// layer. The composition bounds clip, which applies after the async
Expand Down Expand Up @@ -1305,7 +1308,7 @@ HitTestingTreeNode* APZCTreeManager::PrepareNodeForLayer(
node->GetApzc()->Matches(guid));

Maybe<ParentLayerIntRegion> clipRegion =
parentHasPerspective ? Nothing() : ComputeClipRegion(aLayer);
parentHasPerspective ? Nothing() : ComputeClipRegion(aLayersId, aLayer);
SetHitTestData(node, aLayer, clipRegion, aState.mOverrideFlags.top());
apzc->SetAncestorTransform(aAncestorTransform);

Expand Down Expand Up @@ -1405,7 +1408,7 @@ HitTestingTreeNode* APZCTreeManager::PrepareNodeForLayer(
}

Maybe<ParentLayerIntRegion> clipRegion =
parentHasPerspective ? Nothing() : ComputeClipRegion(aLayer);
parentHasPerspective ? Nothing() : ComputeClipRegion(aLayersId, aLayer);
SetHitTestData(node, aLayer, clipRegion, aState.mOverrideFlags.top());
}

Expand Down Expand Up @@ -3528,10 +3531,13 @@ LayerToParentLayerMatrix4x4 APZCTreeManager::ComputeTransformForNode(
// If the node represents scrollable content, apply the async transform
// from its APZC.
bool visualTransformIsInheritedFromAncestor =
apzc->IsRootContent() && /* we're the APZC whose visual transform
might be on the async zoom container */
mUsingAsyncZoomContainer && /* there is an async zoom container */
!aNode->IsAsyncZoomContainer(); /* it's not us */
/* we're the APZC whose visual transform might be on the async
zoom container */
apzc->IsRootContent() &&
/* there is an async zoom container on this subtree */
mAsyncZoomContainerSubtree == Some(aNode->GetLayersId()) &&
/* it's not us */
!aNode->IsAsyncZoomContainer();
AsyncTransformComponents components =
visualTransformIsInheritedFromAncestor
? AsyncTransformComponents{AsyncTransformComponent::eLayout}
Expand Down
9 changes: 5 additions & 4 deletions gfx/layers/apz/src/APZCTreeManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -712,7 +712,8 @@ class APZCTreeManager : public IAPZCTreeManager, public APZInputBridge {
const AncestorTransform& aAncestorTransform, HitTestingTreeNode* aParent,
HitTestingTreeNode* aNextSibling, TreeBuildingState& aState);
template <class ScrollNode>
Maybe<ParentLayerIntRegion> ComputeClipRegion(const ScrollNode& aLayer);
Maybe<ParentLayerIntRegion> ComputeClipRegion(const LayersId& aLayersId,
const ScrollNode& aLayer);

template <class ScrollNode>
void PrintAPZCInfo(const ScrollNode& aLayer,
Expand Down Expand Up @@ -796,10 +797,10 @@ class APZCTreeManager : public IAPZCTreeManager, public APZInputBridge {
*/
std::unordered_set<LayersId, LayersId::HashFn> mDetachedLayersIds;

/* True if the current hit-testing tree contains an async zoom container
* node.
/* If the current hit-testing tree contains an async zoom container
* node, this is set to the layers id of subtree that has the node.
*/
bool mUsingAsyncZoomContainer;
Maybe<LayersId> mAsyncZoomContainerSubtree;

/** A lock that protects mApzcMap, mScrollThumbInfo, mRootScrollbarInfo,
* mFixedPositionInfo, and mStickyPositionInfo.
Expand Down

0 comments on commit bf0c5bb

Please sign in to comment.