commit 718cc9cec13a37bfc4c1fbfa8333dc086d2f8512
parent 18b3d129d06daf968131a3c8416413f2e2fd3366
Author: Emilio Cobos Álvarez <emilio@crisal.io>
Date: Wed, 29 Oct 2025 13:00:04 +0000
Bug 1997040 - Make DepthOrderedFrameList insertion not scan the whole array. r=jfkthame,layout-reviewers
Differential Revision: https://phabricator.services.mozilla.com/D270483
Diffstat:
2 files changed, 15 insertions(+), 13 deletions(-)
diff --git a/layout/base/DepthOrderedFrameList.cpp b/layout/base/DepthOrderedFrameList.cpp
@@ -13,19 +13,16 @@ namespace mozilla {
void DepthOrderedFrameList::Add(nsIFrame* aFrame) {
// Is this root already scheduled for reflow?
- // FIXME: This could possibly be changed to a uniqueness assertion, with some
- // work in ResizeReflowIgnoreOverride (and maybe others?)
- // FIXME(emilio): Should probably reuse the traversal for insertion.
- if (Contains(aFrame)) {
- // We don't expect frame to change depths.
- MOZ_ASSERT(aFrame->GetDepthInFrameTree() ==
- mList[mList.IndexOf(aFrame)].mDepth);
+ FrameAndDepth entry{aFrame, aFrame->GetDepthInFrameTree()};
+ auto index = mList.IndexOfFirstElementGt(
+ entry, FrameAndDepth::CompareByReverseDepth{});
+ if (MOZ_UNLIKELY(index > 0 && mList[index - 1].mFrame == aFrame)) {
+ // FIXME: This could possibly be changed to a uniqueness assertion, with
+ // some work in ResizeReflowIgnoreOverride (and maybe others?)
+ MOZ_ASSERT(mList[index - 1].mDepth == entry.mDepth);
return;
}
-
- mList.InsertElementSorted(
- FrameAndDepth{aFrame, aFrame->GetDepthInFrameTree()},
- FrameAndDepth::CompareByReverseDepth{});
+ mList.InsertElementAt(index, std::move(entry));
}
void DepthOrderedFrameList::Remove(nsIFrame* aFrame) {
diff --git a/layout/base/DepthOrderedFrameList.h b/layout/base/DepthOrderedFrameList.h
@@ -52,11 +52,16 @@ class DepthOrderedFrameList {
class CompareByReverseDepth {
public:
bool Equals(const FrameAndDepth& aA, const FrameAndDepth& aB) const {
- return aA.mDepth == aB.mDepth;
+ return aA.mFrame == aB.mFrame;
}
bool LessThan(const FrameAndDepth& aA, const FrameAndDepth& aB) const {
// Reverse depth! So '>' instead of '<'.
- return aA.mDepth > aB.mDepth;
+ if (aA.mDepth != aB.mDepth) {
+ return aA.mDepth > aB.mDepth;
+ }
+ // Untie with the frame pointer, so that all frames have a unique
+ // position in the sorted list.
+ return uintptr_t(aA.mFrame) < uintptr_t(aB.mFrame);
}
};
};