Bug 732429 - Move some code from nsSVGOuterSVGFrame::Paint to nsDisplaySVG::Paint. r=longsonr.
authorJonathan Watt <jwatt@jwatt.org>
Fri, 02 Mar 2012 23:38:36 +0000
changeset 88183 2b4aed5ee94e035a7cee32c308ca9b8590a426bb
parent 88182 5a9bd18c627ae6a01f83194345c8785f95b2c664
child 88184 c228a0a6f2ceb822edc5700c9a73b89d9159a3cf
push id22173
push userbmo@edmorley.co.uk
push dateSat, 03 Mar 2012 13:14:42 +0000
treeherdermozilla-central@ed57abebd328 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslongsonr
bugs732429
milestone13.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 732429 - Move some code from nsSVGOuterSVGFrame::Paint to nsDisplaySVG::Paint. r=longsonr.
layout/svg/base/src/nsSVGOuterSVGFrame.cpp
layout/svg/base/src/nsSVGOuterSVGFrame.h
--- a/layout/svg/base/src/nsSVGOuterSVGFrame.cpp
+++ b/layout/svg/base/src/nsSVGOuterSVGFrame.cpp
@@ -500,20 +500,80 @@ nsDisplaySVG::HitTest(nsDisplayListBuild
                    outerSVGFrame->GetContentRect().TopLeft());
   if (frame) {
     aOutFrames->AppendElement(frame);
   }
 }
 
 void
 nsDisplaySVG::Paint(nsDisplayListBuilder* aBuilder,
-                    nsRenderingContext* aCtx)
+                    nsRenderingContext* aContext)
 {
-  static_cast<nsSVGOuterSVGFrame*>(mFrame)->
-    Paint(aBuilder, aCtx, mVisibleRect, ToReferenceFrame());
+  nsSVGOuterSVGFrame *frame = static_cast<nsSVGOuterSVGFrame*>(mFrame);
+
+  if (frame->GetStateBits() & NS_STATE_SVG_NONDISPLAY_CHILD)
+    return;
+
+#if defined(DEBUG) && defined(SVG_DEBUG_PAINT_TIMING)
+  PRTime start = PR_Now();
+#endif
+
+  aContext->PushState();
+
+#ifdef XP_MACOSX
+  if (frame->BitmapFallbackEnabled()) {
+    // nquartz fallback paths, which svg tends to trigger, need
+    // a non-window context target
+    aContext->ThebesContext()->PushGroup(gfxASurface::CONTENT_COLOR_ALPHA);
+  }
+#endif
+
+  frame->Paint(aBuilder, aContext, mVisibleRect, ToReferenceFrame());
+
+#ifdef XP_MACOSX
+  if (frame->BitmapFallbackEnabled()) {
+    // show the surface we pushed earlier for fallbacks
+    aContext->ThebesContext()->PopGroupToSource();
+    aContext->ThebesContext()->Paint();
+  }
+
+  if (aContext->ThebesContext()->HasError() && !frame->BitmapFallbackEnabled()) {
+    frame->SetBitmapFallbackEnabled(true);
+    // It's not really clear what area to invalidate here. We might have
+    // stuffed up rendering for the entire window in this paint pass,
+    // so we can't just invalidate our own rect. Invalidate everything
+    // in sight.
+    // This won't work for printing, by the way, but failure to print the
+    // odd document is probably no worse than printing horribly for all
+    // documents. Better to fix things so we don't need fallback.
+    nsIFrame* ancestor = frame;
+    PRUint32 flags = 0;
+    while (true) {
+      nsIFrame* next = nsLayoutUtils::GetCrossDocParentFrame(ancestor);
+      if (!next)
+        break;
+      if (ancestor->GetParent() != next) {
+        // We're crossing a document boundary. Logically, the invalidation is
+        // being triggered by a subdocument of the root document. This will
+        // prevent an untrusted root document being told about invalidation
+        // that happened because a child was using SVG...
+        flags |= nsIFrame::INVALIDATE_CROSS_DOC;
+      }
+      ancestor = next;
+    }
+    ancestor->InvalidateWithFlags(nsRect(nsPoint(0, 0), ancestor->GetSize()), flags);
+  }
+#endif
+
+  aContext->PopState();
+
+#if defined(DEBUG) && defined(SVG_DEBUG_PAINT_TIMING)
+  PRTime end = PR_Now();
+  printf("SVG Paint Timing: %f ms\n", (end-start)/1000.0);
+#endif
 }
 
 // helper
 static inline bool
 DependsOnIntrinsicSize(const nsIFrame* aEmbeddingFrame)
 {
   const nsStylePosition *pos = aEmbeddingFrame->GetStylePosition();
   const nsStyleCoord &width = pos->mWidth;
@@ -583,97 +643,37 @@ nsSVGOuterSVGFrame::BuildDisplayList(nsD
       new (aBuilder) nsDisplaySVG(aBuilder, this));
 }
 
 void
 nsSVGOuterSVGFrame::Paint(const nsDisplayListBuilder* aBuilder,
                           nsRenderingContext* aContext,
                           const nsRect& aDirtyRect, nsPoint aPt)
 {
-  if (GetStateBits() & NS_STATE_SVG_NONDISPLAY_CHILD)
-    return;
-
-  // initialize Mozilla rendering context
-  aContext->PushState();
-
   nsRect viewportRect = GetContentRect();
   nsPoint viewportOffset = aPt + viewportRect.TopLeft() - GetPosition();
   viewportRect.MoveTo(viewportOffset);
 
   nsRect clipRect;
   clipRect.IntersectRect(aDirtyRect, viewportRect);
   aContext->IntersectClip(clipRect);
   aContext->Translate(viewportRect.TopLeft());
   nsRect dirtyRect = clipRect - viewportOffset;
 
-#if defined(DEBUG) && defined(SVG_DEBUG_PAINT_TIMING)
-  PRTime start = PR_Now();
-#endif
-
   nsIntRect dirtyPxRect = dirtyRect.ToOutsidePixels(PresContext()->AppUnitsPerDevPixel());
 
   // Create an SVGAutoRenderState so we can call SetPaintingToWindow on
   // it, but don't change the render mode:
   SVGAutoRenderState state(aContext, SVGAutoRenderState::GetRenderMode(aContext));
 
   if (aBuilder->IsPaintingToWindow()) {
     state.SetPaintingToWindow(true);
   }
 
-#ifdef XP_MACOSX
-  if (mEnableBitmapFallback) {
-    // nquartz fallback paths, which svg tends to trigger, need
-    // a non-window context target
-    aContext->ThebesContext()->PushGroup(gfxASurface::CONTENT_COLOR_ALPHA);
-  }
-#endif
-
   nsSVGUtils::PaintFrameWithEffects(aContext, &dirtyPxRect, this);
-
-#ifdef XP_MACOSX
-  if (mEnableBitmapFallback) {
-    // show the surface we pushed earlier for fallbacks
-    aContext->ThebesContext()->PopGroupToSource();
-    aContext->ThebesContext()->Paint();
-  }
-  
-  if (aContext->ThebesContext()->HasError() && !mEnableBitmapFallback) {
-    mEnableBitmapFallback = true;
-    // It's not really clear what area to invalidate here. We might have
-    // stuffed up rendering for the entire window in this paint pass,
-    // so we can't just invalidate our own rect. Invalidate everything
-    // in sight.
-    // This won't work for printing, by the way, but failure to print the
-    // odd document is probably no worse than printing horribly for all
-    // documents. Better to fix things so we don't need fallback.
-    nsIFrame* frame = this;
-    PRUint32 flags = 0;
-    while (true) {
-      nsIFrame* next = nsLayoutUtils::GetCrossDocParentFrame(frame);
-      if (!next)
-        break;
-      if (frame->GetParent() != next) {
-        // We're crossing a document boundary. Logically, the invalidation is
-        // being triggered by a subdocument of the root document. This will
-        // prevent an untrusted root document being told about invalidation
-        // that happened because a child was using SVG...
-        flags |= INVALIDATE_CROSS_DOC;
-      }
-      frame = next;
-    }
-    frame->InvalidateWithFlags(nsRect(nsPoint(0, 0), frame->GetSize()), flags);
-  }
-#endif
-
-#if defined(DEBUG) && defined(SVG_DEBUG_PAINT_TIMING)
-  PRTime end = PR_Now();
-  printf("SVG Paint Timing: %f ms\n", (end-start)/1000.0);
-#endif
-  
-  aContext->PopState();
 }
 
 nsSplittableType
 nsSVGOuterSVGFrame::GetSplittableType() const
 {
   return NS_FRAME_NOT_SPLITTABLE;
 }
 
--- a/layout/svg/base/src/nsSVGOuterSVGFrame.h
+++ b/layout/svg/base/src/nsSVGOuterSVGFrame.h
@@ -135,16 +135,26 @@ public:
   /* Methods to allow descendant nsSVGForeignObjectFrame frames to register and
    * unregister themselves with their nearest nsSVGOuterSVGFrame ancestor so
    * they can be reflowed. The methods return true on success or false on
    * failure.
    */
   void RegisterForeignObject(nsSVGForeignObjectFrame* aFrame);
   void UnregisterForeignObject(nsSVGForeignObjectFrame* aFrame);
 
+#ifdef XP_MACOSX
+  bool BitmapFallbackEnabled() const {
+    return mEnableBitmapFallback;
+  }
+  void SetBitmapFallbackEnabled(bool aVal) {
+    NS_NOTREACHED("don't think me need this any more"); // comment in bug 732429 if we do
+    mEnableBitmapFallback = aVal;
+  }
+#endif
+
 protected:
 
   /* Returns true if our content is the document element and our document is
    * embedded in an HTML 'object', 'embed' or 'applet' element. Set
    * aEmbeddingFrame to obtain the nsIFrame for the embedding HTML element.
    */
   bool IsRootOfReplacedElementSubDoc(nsIFrame **aEmbeddingFrame = nsnull);