tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 5416d09b794a15b439a490addaa1b13f1d59de28
parent aa124118714b8171a27d35a2820bd45c51eaec36
Author: iulian moraru <imoraru@mozilla.com>
Date:   Sat,  4 Oct 2025 14:19:50 +0300

Revert "Bug 1991689 - Cache a PropertyProvider in SVGTextFrame so that we don't have to create a fresh one for every call to the same textframe. r=firefox-svg-reviewers,longsonr" for causing multiple failures.

This reverts commit aa124118714b8171a27d35a2820bd45c51eaec36.

Revert "Bug 1991689 - Cache advances of text ranges measured by TextRenderedRun::GetClipEdges in the root SVGTextFrame to accelerate ReflowSVG. r=firefox-svg-reviewers,longsonr"

This reverts commit 4bc276362491d28731154efdf229b95463e4ef29.

Diffstat:
Mgfx/thebes/gfxTextRun.h | 4----
Mlayout/generic/nsTextFrame.h | 7++-----
Mlayout/svg/SVGTextFrame.cpp | 87++++++++++++++++++++++++++-----------------------------------------------------
Mlayout/svg/SVGTextFrame.h | 42------------------------------------------
4 files changed, 30 insertions(+), 110 deletions(-)

diff --git a/gfx/thebes/gfxTextRun.h b/gfx/thebes/gfxTextRun.h @@ -163,10 +163,6 @@ class gfxTextRun : public gfxShapedText { Range(uint32_t aStart, uint32_t aEnd) : start(aStart), end(aEnd) {} explicit Range(const gfxTextRun* aTextRun) : Range(0, aTextRun->GetLength()) {} - - bool Intersects(const Range& aOther) const { - return start < aOther.end && end > aOther.start; - } }; // All coordinates are in layout/app units diff --git a/layout/generic/nsTextFrame.h b/layout/generic/nsTextFrame.h @@ -112,12 +112,9 @@ class nsTextFrame : public nsIFrame { /** * An implementation of gfxTextRun::PropertyProvider that computes spacing and * hyphenation based on CSS properties for a text frame. - * - * nsTextFrame normally creates a PropertyProvider as a temporary object on - * on the stack, but this is not marked MOZ_STACK_CLASS because SVGTextFrame - * wants to cache an instance across multiple calls using the same textframe. */ - class PropertyProvider final : public gfxTextRun::PropertyProvider { + class MOZ_STACK_CLASS PropertyProvider final + : public gfxTextRun::PropertyProvider { using HyphenType = gfxTextRun::HyphenType; public: diff --git a/layout/svg/SVGTextFrame.cpp b/layout/svg/SVGTextFrame.cpp @@ -409,14 +409,13 @@ struct TextRenderedRun { * paint it. See the comments documenting the member variables below * for descriptions of the arguments. */ - TextRenderedRun(nsTextFrame* aFrame, SVGTextFrame* aSVGTextFrame, - const gfxPoint& aPosition, float aLengthAdjustScaleFactor, - double aRotate, float aFontSizeScaleFactor, nscoord aBaseline, + TextRenderedRun(nsTextFrame* aFrame, const gfxPoint& aPosition, + float aLengthAdjustScaleFactor, double aRotate, + float aFontSizeScaleFactor, nscoord aBaseline, uint32_t aTextFrameContentOffset, uint32_t aTextFrameContentLength, uint32_t aTextElementCharIndex) : mFrame(aFrame), - mRoot(aSVGTextFrame), mPosition(aPosition), mLengthAdjustScaleFactor(aLengthAdjustScaleFactor), mRotate(static_cast<float>(aRotate)), @@ -663,11 +662,6 @@ struct TextRenderedRun { nsTextFrame* mFrame; /** - * The SVGTextFrame to which our text frame belongs. - */ - SVGTextFrame* mRoot; - - /** * The point in user space that the text is positioned at. * * For a horizontal run: @@ -835,6 +829,7 @@ SVGBBox TextRenderedRun::GetRunUserSpaceRect(nsPresContext* aContext, vertical ? -self.y : -self.x); gfxSkipCharsIterator it = mFrame->EnsureTextRun(nsTextFrame::eInflated); + gfxSkipCharsIterator start = it; gfxTextRun* textRun = mFrame->GetTextRun(nsTextFrame::eInflated); // Get the content range for this rendered run. @@ -844,7 +839,10 @@ SVGBBox TextRenderedRun::GetRunUserSpaceRect(nsPresContext* aContext, return r; } - auto& provider = mRoot->PropertyProviderFor(mFrame); + // FIXME(heycam): We could create a single PropertyProvider for all + // TextRenderedRuns that correspond to the text frame, rather than recreate + // it each time here. + nsTextFrame::PropertyProvider provider(mFrame, start); // Measure that range. gfxTextRun::Metrics metrics = textRun->MeasureText( @@ -942,7 +940,7 @@ void TextRenderedRun::GetClipEdges(nscoord& aVisIStartEdge, gfxSkipCharsIterator it = mFrame->EnsureTextRun(nsTextFrame::eInflated); gfxTextRun* textRun = mFrame->GetTextRun(nsTextFrame::eInflated); - auto& provider = mRoot->PropertyProviderFor(mFrame); + nsTextFrame::PropertyProvider provider(mFrame, it); // Get the covered content offset/length for this rendered run in skipped // characters, since that is what GetAdvanceWidth expects. @@ -964,43 +962,15 @@ void TextRenderedRun::GetClipEdges(nscoord& aVisIStartEdge, // characters. Range frameRange = ConvertOriginalToSkipped(it, frameOffset, frameLength); - // Get the advance of aRange, using the aCachedRange if available to - // accelerate textrun measurement. - auto MeasureUsingCache = [&](SVGTextFrame::CachedMeasuredRange& aCachedRange, - const Range& aRange) -> nscoord { - if (aRange.Intersects(aCachedRange.mRange)) { - // We only need to measure the differences between the cached range and - // aRange. - // TODO: check whether this will in fact involve less measurement! - if (aRange.start < aCachedRange.mRange.start) { - aCachedRange.mAdvance += textRun->GetAdvanceWidth( - Range(aRange.start, aCachedRange.mRange.start), &provider); - } else if (aRange.start > aCachedRange.mRange.start) { - aCachedRange.mAdvance -= textRun->GetAdvanceWidth( - Range(aCachedRange.mRange.start, aRange.start), &provider); - } - if (aRange.end > aCachedRange.mRange.end) { - aCachedRange.mAdvance += textRun->GetAdvanceWidth( - Range(aCachedRange.mRange.end, aRange.end), &provider); - } else if (aRange.end < aCachedRange.mRange.end) { - aCachedRange.mAdvance -= textRun->GetAdvanceWidth( - Range(aRange.end, aCachedRange.mRange.end), &provider); - } - } else { - // Just measure the range, and cache the result. - aCachedRange.mAdvance = textRun->GetAdvanceWidth(aRange, &provider); - } - aCachedRange.mRange = aRange; - return aCachedRange.mAdvance; - }; + // Measure the advance width in the text run between the start of + // frame's content and the start of the rendered run's content, + nscoord startEdge = textRun->GetAdvanceWidth( + Range(frameRange.start, runRange.start), &provider); - mRoot->SetCurrentFrameForCaching(mFrame); - nscoord startEdge = - MeasureUsingCache(mRoot->CachedRange(SVGTextFrame::WhichRange::Before), - Range(frameRange.start, runRange.start)); + // and between the end of the rendered run's content and the end + // of the frame's content. nscoord endEdge = - MeasureUsingCache(mRoot->CachedRange(SVGTextFrame::WhichRange::After), - Range(runRange.end, frameRange.end)); + textRun->GetAdvanceWidth(Range(runRange.end, frameRange.end), &provider); if (textRun->IsRightToLeft()) { aVisIStartEdge = endEdge; @@ -1014,7 +984,7 @@ void TextRenderedRun::GetClipEdges(nscoord& aVisIStartEdge, nscoord TextRenderedRun::GetAdvanceWidth() const { gfxSkipCharsIterator it = mFrame->EnsureTextRun(nsTextFrame::eInflated); gfxTextRun* textRun = mFrame->GetTextRun(nsTextFrame::eInflated); - auto& provider = mRoot->PropertyProviderFor(mFrame); + nsTextFrame::PropertyProvider provider(mFrame, it); Range range = ConvertOriginalToSkipped(it, mTextFrameContentOffset, mTextFrameContentLength); @@ -1064,7 +1034,7 @@ int32_t TextRenderedRun::GetCharNumAtPosition(nsPresContext* aContext, gfxSkipCharsIterator it = mFrame->EnsureTextRun(nsTextFrame::eInflated); gfxTextRun* textRun = mFrame->GetTextRun(nsTextFrame::eInflated); - auto& provider = mRoot->PropertyProviderFor(mFrame); + nsTextFrame::PropertyProvider provider(mFrame, it); // Next check that the point lies horizontally within the left and right // edges of the text. @@ -1930,9 +1900,9 @@ TextRenderedRun TextRenderedRunIterator::Next() { } } - mCurrent = TextRenderedRun( - frame, Root(), pt, Root()->mLengthAdjustScaleFactor, rotate, - mFontSizeScaleFactor, baseline, offset, length, charIndex); + mCurrent = TextRenderedRun(frame, pt, Root()->mLengthAdjustScaleFactor, + rotate, mFontSizeScaleFactor, baseline, offset, + length, charIndex); return mCurrent; } @@ -2351,7 +2321,10 @@ gfxFloat CharIterator::GetAdvance(nsPresContext* aContext) const { float cssPxPerDevPx = nsPresContext::AppUnitsToFloatCSSPixels(aContext->AppUnitsPerDevPixel()); - auto& provider = mFrameIterator.Root()->PropertyProviderFor(TextFrame()); + gfxSkipCharsIterator start = + TextFrame()->EnsureTextRun(nsTextFrame::eInflated); + nsTextFrame::PropertyProvider provider(TextFrame(), start); + uint32_t offset = mSkipCharsIterator.GetSkippedOffset(); gfxFloat advance = mTextRun->GetAdvanceWidth(Range(offset, offset + 1), &provider); @@ -3707,7 +3680,7 @@ float SVGTextFrame::GetSubStringLengthFastPath(nsIContent* aContent, gfxSkipCharsIterator it = frame->EnsureTextRun(nsTextFrame::eInflated); gfxTextRun* textRun = frame->GetTextRun(nsTextFrame::eInflated); - auto& provider = PropertyProviderFor(frame); + nsTextFrame::PropertyProvider provider(frame, it); Range range = ConvertOriginalToSkipped(it, offset, trimmedLength); @@ -3775,7 +3748,7 @@ float SVGTextFrame::GetSubStringLengthSlowFallback(nsIContent* aContent, gfxSkipCharsIterator it = run.mFrame->EnsureTextRun(nsTextFrame::eInflated); gfxTextRun* textRun = run.mFrame->GetTextRun(nsTextFrame::eInflated); - auto& provider = PropertyProviderFor(run.mFrame); + nsTextFrame::PropertyProvider provider(run.mFrame, it); Range range = ConvertOriginalToSkipped(it, offset, length); @@ -4330,7 +4303,7 @@ void SVGTextFrame::DetermineCharPositions(nsTArray<nsPoint>& aPositions) { for (nsTextFrame* frame = frit.Current(); frame; frame = frit.Next()) { gfxSkipCharsIterator it = frame->EnsureTextRun(nsTextFrame::eInflated); gfxTextRun* textRun = frame->GetTextRun(nsTextFrame::eInflated); - auto& provider = PropertyProviderFor(frame); + nsTextFrame::PropertyProvider provider(frame, it); // Reset the position to the new frame's position. position = frit.Position(); @@ -5135,10 +5108,6 @@ void SVGTextFrame::DoReflow() { RemoveStateBits(NS_FRAME_IS_DIRTY | NS_FRAME_HAS_DIRTY_CHILDREN); } - // Forget any cached measurements of one of our children. - mFrameForCachedRanges = nullptr; - mCachedProvider.reset(); - nsPresContext* presContext = PresContext(); nsIFrame* kid = PrincipalChildList().FirstChild(); if (!kid) { diff --git a/layout/svg/SVGTextFrame.h b/layout/svg/SVGTextFrame.h @@ -11,7 +11,6 @@ #include "gfxRect.h" #include "gfxTextRun.h" #include "mozilla/Attributes.h" -#include "mozilla/Maybe.h" #include "mozilla/PresShellForwards.h" #include "mozilla/RefPtr.h" #include "mozilla/SVGContainerFrame.h" @@ -587,47 +586,6 @@ class SVGTextFrame final : public SVGDisplayContainerFrame { * lengthAdjust="spacingAndGlyphs". */ float mLengthAdjustScaleFactor = 1.0f; - - public: - struct CachedMeasuredRange { - Range mRange; - nscoord mAdvance; - }; - - void SetCurrentFrameForCaching(const nsTextFrame* aFrame) { - if (mFrameForCachedRanges != aFrame) { - PodArrayZero(mCachedRanges); - mFrameForCachedRanges = aFrame; - } - } - - enum WhichRange { - Before, - After, - CachedRangeCount, - }; - - CachedMeasuredRange& CachedRange(WhichRange aWhichRange) { - return mCachedRanges[aWhichRange]; - } - - // Return a reference to a PropertyProvider for the given textframe; - // the provider is cached by SVGTextFrame to avoid creating it afresh - // for repeated operations involving the same textframe. - nsTextFrame::PropertyProvider& PropertyProviderFor(nsTextFrame* aFrame) { - if (!mCachedProvider || aFrame != mCachedProvider->GetFrame()) { - mCachedProvider.reset(); - mCachedProvider.emplace(aFrame, - aFrame->EnsureTextRun(nsTextFrame::eInflated)); - } - return mCachedProvider.ref(); - } - - private: - const nsTextFrame* mFrameForCachedRanges = nullptr; - CachedMeasuredRange mCachedRanges[CachedRangeCount]; - - Maybe<nsTextFrame::PropertyProvider> mCachedProvider; }; } // namespace mozilla