Bug 1325038 - Part 1. Correct assertion logic. draft
authorcku <cku@mozilla.com>
Thu, 12 Jan 2017 16:38:48 +0800
changeset 459654 0236a1a33dca3aa7985f4bc166e2e0aeb03fca8b
parent 459458 13603af3862d9583ed2feefb06e0988c2d7fed8c
child 459655 b633d0392eff18e1915071ac8a4eb42cda765280
push id41287
push usercku@mozilla.com
push dateThu, 12 Jan 2017 11:53:23 +0000
bugs1325038, 1324809
milestone53.0a1
Bug 1325038 - Part 1. Correct assertion logic. In the test case of bug 1324809: 1. A span is been broken into two continuation frames: FA and FB. FA is the first connituation 2. Adding a filter effect to this span. 3. FA::FinishAndStoreOverflow is called. This function will call ComputeEffect: if (nsSVGIntegrationUtils::UsingEffectsForFrame(aFrame)) { aFrame->Properties(). Set(nsIFrame::PreEffectsBBoxProperty(), new nsRect(r)); // Now FA has // PreEffectsBBoxProperty // but FB does not // have yet. // ComputePostEffectsVisualOverflowRect will iterate all continuations from // FA to FB. At this moment, FB does not carry PreEffectsBBoxProperty, // assertion failure. r = nsSVGIntegrationUtils::ComputePostEffectsVisualOverflowRect(aFrame, r); } 4. FB::FinishAndStoreOverflow is called. But already too late. MozReview-Commit-ID: 2c8OFzSLhfD *** merge MozReview-Commit-ID: C0lYQkKCYT6
layout/svg/nsSVGIntegrationUtils.cpp
--- a/layout/svg/nsSVGIntegrationUtils.cpp
+++ b/layout/svg/nsSVGIntegrationUtils.cpp
@@ -21,16 +21,17 @@
 #include "nsSVGMaskFrame.h"
 #include "nsSVGPaintServerFrame.h"
 #include "nsSVGUtils.h"
 #include "FrameLayerBuilder.h"
 #include "BasicLayers.h"
 #include "mozilla/gfx/Point.h"
 #include "nsCSSRendering.h"
 #include "mozilla/Unused.h"
+#include "mozilla/RestyleManager.h"
 
 using namespace mozilla;
 using namespace mozilla::layers;
 using namespace mozilla::gfx;
 using namespace mozilla::image;
 
 // ----------------------------------------------------------------------
 
@@ -105,28 +106,38 @@ private:
     //
     //  * reftests/svg/svg-integration/clipPath-html-06.xhtml
     //  * reftests/svg/svg-integration/clipPath-html-06-extref.xhtml
     //
     // If we ever got passed a frame with the PreTransformOverflowAreasProperty
     // property set, that would be bad, since then our GetVisualOverflowRect()
     // call would give us the post-effects, and post-transform, overflow rect.
     //
-    // With image masks, there is one more exception.
-    //
-    // In nsStyleImageLayers::Layer::CalcDifference, we do not add
-    // nsChangeHint_UpdateOverflow hint when image mask(not SVG mask) property
-    // value changed, since replace image mask does not cause layout change.
-    // So even if we apply a new mask image to this frame,
-    // PreEffectsBBoxProperty might still left empty.
-    NS_ASSERTION(nsSVGEffects::GetEffectProperties(aFrame).MightHaveNoneSVGMask() ||
+    // There are two more exceptions:
+    // 1. In nsStyleImageLayers::Layer::CalcDifference, we do not add
+    //    nsChangeHint_UpdateOverflow hint when image mask(not SVG mask)
+    //    property value changed, since replace image mask does not cause
+    //    layout change. So even if we apply a new mask image to this frame,
+    //    PreEffectsBBoxProperty might still left empty.
+    // 2. During restyling: before the last continuation is restyled, there
+    //    is no guarantee that every continuation carries a
+    //    PreEffectsBBoxProperty property.
+#ifdef DEBUG
+    nsIFrame* firstFrame =
+      nsLayoutUtils::FirstContinuationOrIBSplitSibling(aFrame);
+    bool mightHaveNoneSVGMask =
+      nsSVGEffects::GetEffectProperties(firstFrame).MightHaveNoneSVGMask();
+    bool inRestyle =
+      aFrame->PresContext()->RestyleManager()->AsGecko()->IsInStyleRefresh();
+
+    NS_ASSERTION(mightHaveNoneSVGMask || inRestyle ||
                  aFrame->GetParent()->StyleContext()->GetPseudo() ==
                    nsCSSAnonBoxes::mozAnonymousBlock,
                  "How did we getting here, then?");
-
+#endif
     NS_ASSERTION(!aFrame->Properties().Get(
                    aFrame->PreTransformOverflowAreasProperty()),
                  "GetVisualOverflowRect() won't return the pre-effects rect!");
     return aFrame->GetVisualOverflowRect();
   }
 
   nsIFrame*     mFirstContinuation;
   nsIFrame*     mCurrentFrame;