Bug 1441916 - Replace the code to clear focus targets with the simpler hook. r?botond
Instead of keeping track of all the layers ids that we've seen during
the tree walk, we can now just get notified when a layer subtree is
removed, and clear out the state for that layers id at that point.
MozReview-Commit-ID: DVlWX3upWJ6
--- a/gfx/layers/apz/src/APZCTreeManager.cpp
+++ b/gfx/layers/apz/src/APZCTreeManager.cpp
@@ -88,21 +88,16 @@ struct APZCTreeManager::TreeBuildingStat
const APZPaintLogHelper mPaintLogger;
// State that is updated as we perform the tree build
// A list of nodes that need to be destroyed at the end of the tree building.
// This is initialized with all nodes in the old tree, and nodes are removed
// from it as we reuse them in the new tree.
nsTArray<RefPtr<HitTestingTreeNode>> mNodesToDestroy;
- // A set of layer trees that are no longer in the hit testing tree. This is
- // used to destroy unneeded focus targets at the end of tree building. This
- // 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.
@@ -264,22 +259,30 @@ APZCTreeManager::InitializeGlobalState()
AsyncPanZoomController::InitializeGlobalState();
}
void
APZCTreeManager::NotifyLayerTreeAdopted(uint64_t aLayersId,
const RefPtr<APZCTreeManager>& aOldApzcTreeManager)
{
APZThreadUtils::AssertOnCompositorThread();
+
+ MOZ_ASSERT(aOldApzcTreeManager);
+ aOldApzcTreeManager->mFocusState.RemoveFocusTarget(aLayersId);
+ // While we could move the focus target information from the old APZC tree
+ // manager into this one, it's safer to not do that, as we'll probably have
+ // that information repopulated soon anyway (on the next layers update).
}
void
APZCTreeManager::NotifyLayerTreeRemoved(uint64_t aLayersId)
{
APZThreadUtils::AssertOnCompositorThread();
+
+ mFocusState.RemoveFocusTarget(aLayersId);
}
AsyncPanZoomController*
APZCTreeManager::NewAPZCInstance(uint64_t aLayersId,
GeckoContentController* aController)
{
return new AsyncPanZoomController(aLayersId, this, mInputQueue,
aController, AsyncPanZoomController::USE_GESTURE_DETECTOR);
@@ -337,30 +340,27 @@ APZCTreeManager::UpdateHitTestingTreeImp
// we are sure that the layer was removed and not just transplanted elsewhere. Doing that
// as part of a recursive tree walk is hard and so maintaining a list and removing
// APZCs that are still alive is much simpler.
ForEachNode<ReverseIterator>(mRootNode.get(),
[&state] (HitTestingTreeNode* aNode)
{
state.mNodesToDestroy.AppendElement(aNode);
});
- state.mLayersIdsToDestroy = mFocusState.GetFocusTargetLayerIds();
mRootNode = nullptr;
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.AssertCurrentThreadIn();
ForEachNode<ReverseIterator>(aRoot,
[&](ScrollNode aLayerMetrics)
{
mApzcTreeLog << aLayerMetrics.Name() << '\t';
@@ -391,19 +391,16 @@ APZCTreeManager::UpdateHitTestingTreeImp
// we would have to set next to node->GetFirstChild().
MOZ_ASSERT(!node->GetFirstChild());
parent = node;
next = nullptr;
// Update the layersId if we have a new one
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;
@@ -453,21 +450,16 @@ APZCTreeManager::UpdateHitTestingTreeImp
for (size_t i = 0; i < state.mNodesToDestroy.Length(); i++) {
APZCTM_LOG("Destroying node at %p with APZC %p\n",
state.mNodesToDestroy[i].get(),
state.mNodesToDestroy[i]->GetApzc());
state.mNodesToDestroy[i]->Destroy();
}
- // Clear out any focus targets that are no longer needed
- for (auto layersId : state.mLayersIdsToDestroy) {
- mFocusState.RemoveFocusTarget(layersId);
- }
-
#if ENABLE_APZCTM_LOGGING
// Make the hit-test tree line up with the layer dump
printf_stderr("APZCTreeManager (%p)\n", this);
mRootNode->Dump(" ");
#endif
}
void
--- a/gfx/layers/apz/src/FocusState.cpp
+++ b/gfx/layers/apz/src/FocusState.cpp
@@ -135,29 +135,16 @@ FocusState::Update(uint64_t aRootLayerTr
}; // struct FocusTargetDataMatcher
if (target.mData.match(FocusTargetDataMatcher{*this, target.mSequenceNumber})) {
return;
}
}
}
-std::unordered_set<uint64_t>
-FocusState::GetFocusTargetLayerIds() const
-{
- std::unordered_set<uint64_t> layersIds;
- layersIds.reserve(mFocusTree.size());
-
- for (const auto& focusNode : mFocusTree) {
- layersIds.insert(focusNode.first);
- }
-
- return layersIds;
-}
-
void
FocusState::RemoveFocusTarget(uint64_t aLayersId)
{
mFocusTree.erase(aLayersId);
}
Maybe<ScrollableLayerGuid>
FocusState::GetHorizontalTarget() const
--- a/gfx/layers/apz/src/FocusState.h
+++ b/gfx/layers/apz/src/FocusState.h
@@ -102,21 +102,16 @@ public:
* @param aOriginatingLayersId the layer tree ID that this focus target
belongs to
*/
void Update(uint64_t aRootLayerTreeId,
uint64_t aOriginatingLayersId,
const FocusTarget& aTarget);
/**
- * Collects a set of the layer tree IDs that we have a focus target for.
- */
- std::unordered_set<uint64_t> GetFocusTargetLayerIds() const;
-
- /**
* Removes a focus target by its layer tree ID.
*/
void RemoveFocusTarget(uint64_t aLayersId);
/**
* Gets the scrollable layer that should be horizontally scrolled for a key
* event, if any. The returned ScrollableLayerGuid doesn't contain a presShellId,
* and so it should not be used in comparisons.