Bug 1535517 - Don't schedule SVG text reflow in response to bidi resolution. r=jwatt
authorCameron McCormack <cam@mcc.id.au>
Fri, 15 Mar 2019 15:29:33 +0000
changeset 464912 7517b9beb5e6ee204af8bd1f829fe9d578cc8123
parent 464911 88a8be92d7ae625c67fb3023c690cf5ae82a0214
child 464913 93c9a0e2da6e07fc65917024e20ab82cd4dc9805
push id35727
push userdvarga@mozilla.com
push dateTue, 19 Mar 2019 09:48:59 +0000
treeherdermozilla-central@70baa37ae1eb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjwatt
bugs1535517
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1535517 - Don't schedule SVG text reflow in response to bidi resolution. r=jwatt Differential Revision: https://phabricator.services.mozilla.com/D23615
layout/svg/SVGTextFrame.cpp
layout/svg/crashtests/1535517-1.svg
layout/svg/crashtests/crashtests.list
--- a/layout/svg/SVGTextFrame.cpp
+++ b/layout/svg/SVGTextFrame.cpp
@@ -5064,26 +5064,37 @@ void SVGTextFrame::MaybeReflowAnonymousB
     if (mState & NS_FRAME_IS_DIRTY) {
       // If we require a full reflow, ensure our kid is marked fully dirty.
       // (Note that our anonymous nsBlockFrame is not an nsSVGDisplayableFrame,
       // so even when we are called via our ReflowSVG this will not be done for
       // us by nsSVGDisplayContainerFrame::ReflowSVG.)
       kid->AddStateBits(NS_FRAME_IS_DIRTY);
     }
 
+    // The RecordCorrespondence and DoReflow calls can result in new text frames
+    // being created (due to bidi resolution or reflow).  We set this bit to
+    // guard against unnecessarily calling back in to
+    // ScheduleReflowSVGNonDisplayText from nsFrame::DidSetComputedStyle on
+    // those new text frames.
+    AddStateBits(NS_STATE_SVG_TEXT_IN_REFLOW);
+
     TextNodeCorrespondenceRecorder::RecordCorrespondence(this);
 
     MOZ_ASSERT(nsSVGUtils::AnyOuterSVGIsCallingReflowSVG(this),
                "should be under ReflowSVG");
     nsPresContext::InterruptPreventer noInterrupts(PresContext());
     DoReflow();
+
+    RemoveStateBits(NS_STATE_SVG_TEXT_IN_REFLOW);
   }
 }
 
 void SVGTextFrame::DoReflow() {
+  MOZ_ASSERT(HasAnyStateBits(NS_STATE_SVG_TEXT_IN_REFLOW));
+
   // Since we are going to reflow the anonymous block frame, we will
   // need to update mPositions.
   // We also mark our text correspondence as dirty since we can end up needing
   // reflow in ways that do not set NS_STATE_SVG_TEXT_CORRESPONDENCE_DIRTY.
   // (We'd then fail the "expected a TextNodeCorrespondenceProperty" assertion
   // when UpdateGlyphPositioning() is called after we return.)
   AddStateBits(NS_STATE_SVG_TEXT_CORRESPONDENCE_DIRTY |
                NS_STATE_SVG_POSITIONING_DIRTY);
@@ -5111,36 +5122,32 @@ void SVGTextFrame::DoReflow() {
       presContext->PresShell()->CreateReferenceRenderingContext();
 
   if (UpdateFontSizeScaleFactor()) {
     // If the font size scale factor changed, we need the block to report
     // an updated preferred width.
     kid->MarkIntrinsicISizesDirty();
   }
 
-  AddStateBits(NS_STATE_SVG_TEXT_IN_REFLOW);
-
   nscoord inlineSize = kid->GetPrefISize(renderingContext);
   WritingMode wm = kid->GetWritingMode();
   ReflowInput reflowInput(presContext, kid, renderingContext,
                           LogicalSize(wm, inlineSize, NS_UNCONSTRAINEDSIZE));
   ReflowOutput desiredSize(reflowInput);
   nsReflowStatus status;
 
   NS_ASSERTION(
       reflowInput.ComputedPhysicalBorderPadding() == nsMargin(0, 0, 0, 0) &&
           reflowInput.ComputedPhysicalMargin() == nsMargin(0, 0, 0, 0),
       "style system should ensure that :-moz-svg-text "
       "does not get styled");
 
   kid->Reflow(presContext, desiredSize, reflowInput, status);
   kid->DidReflow(presContext, &reflowInput);
   kid->SetSize(wm, desiredSize.Size(wm));
-
-  RemoveStateBits(NS_STATE_SVG_TEXT_IN_REFLOW);
 }
 
 // Usable font size range in devpixels / user-units
 #define CLAMP_MIN_SIZE 8.0
 #define CLAMP_MAX_SIZE 200.0
 #define PRECISE_SIZE 200.0
 
 bool SVGTextFrame::UpdateFontSizeScaleFactor() {
new file mode 100644
--- /dev/null
+++ b/layout/svg/crashtests/1535517-1.svg
@@ -0,0 +1,11 @@
+<svg xmlns="http://www.w3.org/2000/svg">
+
+<marker><text><tspan id="x"/></text></marker>
+
+<script>
+window.addEventListener("load", function() {
+  document.getElementById("x").appendChild(document.createTextNode("\u062Ax"));
+}, false);
+</script>
+
+</svg>
--- a/layout/svg/crashtests/crashtests.list
+++ b/layout/svg/crashtests/crashtests.list
@@ -216,10 +216,11 @@ load blob-merging-and-retained-display-l
 load empty-blob-merging.html
 load grouping-empty-bounds.html
 load 1480275.html
 load 1480224.html
 load 1502936.html
 load 1504918.svg
 load perspective-invalidation.html
 load invalid_url.html
+load 1535517-1.svg
 load 1504072.html
 load 1072758.html