Bug 1365831 - Replace assertion that non-display SVG containers are only reflowed with NS_FRAME_IS_DIRTY with a real test of the condition. r=heycam

The primary patch in bug 1308876 causes frames to be reflowed less often
with NS_FRAME_IS_DIRTY, particularly when multiple passes of reflow are
required for the frame or one of its ancestors (which is generally the
case for a document that ends up not having scrollbars).  This change
causes this assert to fire on various SVG tests such as
layout/reftests/svg/svg-integration/conditions-outer-svg-01.xhtml .
This happens because the outer SVG with conditional processing (in this
test, systemLanguage="x") is reflowed due to its parent resizing,
without NS_FRAME_IS_DIRTY set.  This is a relatively normal thing to
happen during reflow; we just didn't have any tests that exercise it.

This patch adds a crashtest that triggers the assertion through the same
mechanism, but with a dynamic change, rather than depending on the
non-dirty reflow triggered by bug 1308876.  (I confirmed locally that
this test does trigger the assertion without this patch, when run in the
crashtest harness.)

I think fundamentally the assertion isn't valid, and we should instead
be testing the condition that it asserts.

MozReview-Commit-ID: D8hjAbjKyuL

--HG--
extra : transplant_source : %98C%3A%B1%93jb%E7%3D%81%19%97%A6%04%0F%88%8B%D2%A35
This commit is contained in:
L. David Baron 2017-05-18 09:24:33 -07:00
parent 024b5bad85
commit 51adf3206b
3 changed files with 36 additions and 6 deletions

View File

@ -0,0 +1,28 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:svg="http://www.w3.org/2000/svg">
<head>
<title>Test of NS_FRAME_IS_NONDISPLAY / NS_FRAME_IS_DIRTY assertion</title>
<!-- reduced from layout/reftests/svg/svg-integration/conditions-outer-svg-01.xhtml
and modified to occur without bug 1308876 patches. -->
<style>
div { position: relative; height: 100px; width: 100px }
svg { position: absolute; top: 0; left: 0; height: 100%; width: 100% }
</style>
<script>
function run() {
var d = document.getElementById("d");
d.offsetHeight;
d.style.height = "50px";
}
</script>
</head>
<body onload="run()">
<div id="d">
<svg:svg systemLanguage="x"></svg:svg>
</div>
</body>
</html>

View File

@ -199,4 +199,5 @@ load 1182496-1.html
load 1209525-1.svg load 1209525-1.svg
load 1223281-1.svg load 1223281-1.svg
load 1348564.svg load 1348564.svg
load conditional-outer-svg-nondirty-reflow-assert.xhtml
load extref-test-1.xhtml load extref-test-1.xhtml

View File

@ -100,18 +100,19 @@ nsSVGContainerFrame::ComputeCustomOverflow(nsOverflowAreas& aOverflowAreas)
* inherited font-size of an ancestor changes, or a delayed webfont loads and * inherited font-size of an ancestor changes, or a delayed webfont loads and
* applies. * applies.
* *
* We assume that any change that requires the anonymous kid of an * However, we only need to do this work if we were reflowed with
* SVGTextFrame to reflow will result in an NS_FRAME_IS_DIRTY reflow. When * NS_FRAME_IS_DIRTY, which implies that all descendants are dirty. When
* that reflow reaches an NS_FRAME_IS_NONDISPLAY frame it would normally * that reflow reaches an NS_FRAME_IS_NONDISPLAY frame it would normally
* stop, but this helper looks for any SVGTextFrame descendants of such * stop, but this helper looks for any SVGTextFrame descendants of such
* frames and marks them NS_FRAME_IS_DIRTY so that the next time that they are * frames and marks them NS_FRAME_IS_DIRTY so that the next time that they
* painted their anonymous kid will first get the necessary reflow. * are painted their anonymous kid will first get the necessary reflow.
*/ */
/* static */ void /* static */ void
nsSVGContainerFrame::ReflowSVGNonDisplayText(nsIFrame* aContainer) nsSVGContainerFrame::ReflowSVGNonDisplayText(nsIFrame* aContainer)
{ {
NS_ASSERTION(aContainer->GetStateBits() & NS_FRAME_IS_DIRTY, if (!(aContainer->GetStateBits() & NS_FRAME_IS_DIRTY)) {
"expected aContainer to be NS_FRAME_IS_DIRTY"); return;
}
NS_ASSERTION((aContainer->GetStateBits() & NS_FRAME_IS_NONDISPLAY) || NS_ASSERTION((aContainer->GetStateBits() & NS_FRAME_IS_NONDISPLAY) ||
!aContainer->IsFrameOfType(nsIFrame::eSVG), !aContainer->IsFrameOfType(nsIFrame::eSVG),
"it is wasteful to call ReflowSVGNonDisplayText on a container " "it is wasteful to call ReflowSVGNonDisplayText on a container "