Bug 1091321, part 4 - Convert nsISVGChildFrame::PaintSVG and related code from nsRenderingContext to gfxContext. r=longsonr
authorJonathan Watt <jwatt@jwatt.org>
Fri, 31 Oct 2014 20:08:54 +0000
changeset 213455 3313505b1b0ebdeea0c615bae0e14a7167137498
parent 213454 dc72e58dd4c2da22053d4aedcf0aaa9194ed2e68
child 213456 ddc50e4998ca4c49a5bf96c9c2c5c378b56025b8
push id27753
push userphilringnalda@gmail.com
push dateSun, 02 Nov 2014 16:27:30 +0000
treeherdermozilla-central@443853a35898 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslongsonr
bugs1091321
milestone36.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 1091321, part 4 - Convert nsISVGChildFrame::PaintSVG and related code from nsRenderingContext to gfxContext. r=longsonr
layout/svg/SVGTextFrame.cpp
layout/svg/SVGTextFrame.h
layout/svg/nsISVGChildFrame.h
layout/svg/nsSVGClipPathFrame.cpp
layout/svg/nsSVGContainerFrame.cpp
layout/svg/nsSVGContainerFrame.h
layout/svg/nsSVGForeignObjectFrame.cpp
layout/svg/nsSVGForeignObjectFrame.h
layout/svg/nsSVGImageFrame.cpp
layout/svg/nsSVGInnerSVGFrame.cpp
layout/svg/nsSVGInnerSVGFrame.h
layout/svg/nsSVGOuterSVGFrame.cpp
layout/svg/nsSVGOuterSVGFrame.h
layout/svg/nsSVGPathGeometryFrame.cpp
layout/svg/nsSVGPathGeometryFrame.h
layout/svg/nsSVGPatternFrame.cpp
layout/svg/nsSVGSwitchFrame.cpp
layout/svg/nsSVGUtils.cpp
--- a/layout/svg/SVGTextFrame.cpp
+++ b/layout/svg/SVGTextFrame.cpp
@@ -3143,35 +3143,37 @@ nsDisplaySVGText::HitTest(nsDisplayListB
     aOutFrames->AppendElement(target);
   }
 }
 
 void
 nsDisplaySVGText::Paint(nsDisplayListBuilder* aBuilder,
                         nsRenderingContext* aCtx)
 {
+  gfxContext* ctx = aCtx->ThebesContext();
+
   gfxContextAutoDisableSubpixelAntialiasing
-    disable(aCtx->ThebesContext(), mDisableSubpixelAA);
+    disable(ctx, mDisableSubpixelAA);
 
   uint32_t appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel();
 
   // ToReferenceFrame includes our mRect offset, but painting takes
   // account of that too. To avoid double counting, we subtract that
   // here.
   nsPoint offset = ToReferenceFrame() - mFrame->GetPosition();
 
   gfxPoint devPixelOffset =
     nsLayoutUtils::PointToGfxPoint(offset, appUnitsPerDevPixel);
 
   gfxMatrix tm = nsSVGIntegrationUtils::GetCSSPxToDevPxMatrix(mFrame) *
                    gfxMatrix::Translation(devPixelOffset);
 
-  aCtx->ThebesContext()->Save();
-  static_cast<SVGTextFrame*>(mFrame)->PaintSVG(aCtx, tm);
-  aCtx->ThebesContext()->Restore();
+  ctx->Save();
+  static_cast<SVGTextFrame*>(mFrame)->PaintSVG(*ctx, tm);
+  ctx->Restore();
 }
 
 // ---------------------------------------------------------------------
 // nsQueryFrame methods
 
 NS_QUERYFRAME_HEAD(SVGTextFrame)
   NS_QUERYFRAME_ENTRY(SVGTextFrame)
 NS_QUERYFRAME_TAIL_INHERITING(SVGTextFrameBase)
@@ -3590,28 +3592,29 @@ ShouldPaintCaret(const TextRenderedRun& 
                                 aThisRun.mTextFrameContentLength) {
     return true;
   }
 
   return false;
 }
 
 nsresult
-SVGTextFrame::PaintSVG(nsRenderingContext* aContext,
+SVGTextFrame::PaintSVG(gfxContext& aContext,
                        const gfxMatrix& aTransform,
                        const nsIntRect *aDirtyRect)
 {
+  DrawTarget& aDrawTarget = *aContext.GetDrawTarget();
+
   nsIFrame* kid = GetFirstPrincipalChild();
   if (!kid)
     return NS_OK;
 
   nsPresContext* presContext = PresContext();
 
-  gfxContext *gfx = aContext->ThebesContext();
-  gfxMatrix initialMatrix = gfx->CurrentMatrix();
+  gfxMatrix initialMatrix = aContext.CurrentMatrix();
 
   if (mState & NS_FRAME_IS_NONDISPLAY) {
     // If we are in a canvas DrawWindow call that used the
     // DRAWWINDOW_DO_NOT_FLUSH flag, then we may still have out
     // of date frames.  Just don't paint anything if they are
     // dirty.
     if (presContext->PresShell()->InDrawWindowNotFlushing() &&
         NS_SUBTREE_DIRTY(this)) {
@@ -3659,78 +3662,82 @@ SVGTextFrame::PaintSVG(nsRenderingContex
   // dev pixels. Here we multiply a CSS-px-to-dev-pixel factor onto aTransform
   // so our non-SVG nsTextFrame children paint correctly.
   float cssPxPerDevPx = presContext->
     AppUnitsToFloatCSSPixels(presContext->AppUnitsPerDevPixel());
   gfxMatrix canvasTMForChildren = aTransform;
   canvasTMForChildren.Scale(cssPxPerDevPx, cssPxPerDevPx);
   initialMatrix.Scale(1 / cssPxPerDevPx, 1 / cssPxPerDevPx);
 
-  gfxContextAutoSaveRestore save(gfx);
-  gfx->NewPath();
-  gfx->Multiply(canvasTMForChildren);
-  gfxMatrix currentMatrix = gfx->CurrentMatrix();
+  gfxContextAutoSaveRestore save(&aContext);
+  aContext.NewPath();
+  aContext.Multiply(canvasTMForChildren);
+  gfxMatrix currentMatrix = aContext.CurrentMatrix();
 
   nsRefPtr<nsCaret> caret = presContext->PresShell()->GetCaret();
   nsRect caretRect;
   nsIFrame* caretFrame = caret->GetPaintGeometry(&caretRect);
 
   TextRenderedRunIterator it(this, TextRenderedRunIterator::eVisibleFrames);
   TextRenderedRun run = it.Current();
+
+  gfxTextContextPaint *outerContextPaint =
+    (gfxTextContextPaint*)aDrawTarget.GetUserData(&gfxTextContextPaint::sUserDataKey);
+
+  nsRenderingContext rendCtx(&aContext);
+
   while (run.mFrame) {
     nsTextFrame* frame = run.mFrame;
 
     // Determine how much of the left and right edges of the text frame we
     // need to ignore.
     SVGCharClipDisplayItem item(run);
 
     // Set up the fill and stroke so that SVG glyphs can get painted correctly
     // when they use context-fill etc.
-    gfx->SetMatrix(initialMatrix);
-    gfxTextContextPaint *outerContextPaint =
-      (gfxTextContextPaint*)aContext->GetDrawTarget()->GetUserData(&gfxTextContextPaint::sUserDataKey);
+    aContext.SetMatrix(initialMatrix);
 
     SVGTextContextPaint contextPaint;
     DrawMode drawMode =
-      SetupContextPaint(gfx->GetDrawTarget(), gfx->CurrentMatrix(),
+      SetupContextPaint(&aDrawTarget, aContext.CurrentMatrix(),
                         frame, outerContextPaint, &contextPaint);
 
     if (int(drawMode) & int(DrawMode::GLYPH_STROKE)) {
       // This may change the gfxContext's transform (for non-scaling stroke),
       // in which case this needs to happen before we call SetMatrix() below.
-      nsSVGUtils::SetupCairoStrokeGeometry(frame, gfx, outerContextPaint);
+      nsSVGUtils::SetupCairoStrokeGeometry(frame, &aContext, outerContextPaint);
     }
 
     // Set up the transform for painting the text frame for the substring
     // indicated by the run.
     gfxMatrix runTransform =
       run.GetTransformFromUserSpaceForPainting(presContext, item) *
       currentMatrix;
-    gfx->SetMatrix(runTransform);
+    aContext.SetMatrix(runTransform);
 
     if (drawMode != DrawMode(0)) {
       nsRect frameRect = frame->GetVisualOverflowRect();
       bool paintSVGGlyphs;
-      if (ShouldRenderAsPath(aContext, frame, paintSVGGlyphs)) {
-        SVGTextDrawPathCallbacks callbacks(aContext, frame,
+      if (ShouldRenderAsPath(&rendCtx, frame, paintSVGGlyphs)) {
+        SVGTextDrawPathCallbacks callbacks(&rendCtx, frame,
                                            matrixForPaintServers,
                                            paintSVGGlyphs);
-        frame->PaintText(aContext, nsPoint(), frameRect, item,
+        frame->PaintText(&rendCtx, nsPoint(), frameRect, item,
                          &contextPaint, &callbacks);
       } else {
-        frame->PaintText(aContext, nsPoint(), frameRect, item,
+        frame->PaintText(&rendCtx, nsPoint(), frameRect, item,
                          &contextPaint, nullptr);
       }
     }
 
     if (frame == caretFrame && ShouldPaintCaret(run, caret)) {
       // XXX Should we be looking at the fill/stroke colours to paint the
       // caret with, rather than using the color property?
-      caret->PaintCaret(nullptr, *aContext->GetDrawTarget(), frame, nsPoint());
-      gfx->NewPath();
+      caret->PaintCaret(nullptr, aDrawTarget, frame, nsPoint());
+      aContext.NewPath();
     }
 
     run = it.Next();
   }
 
   return NS_OK;
 }
 
--- a/layout/svg/SVGTextFrame.h
+++ b/layout/svg/SVGTextFrame.h
@@ -11,18 +11,18 @@
 #include "mozilla/gfx/2D.h"
 #include "gfxMatrix.h"
 #include "gfxRect.h"
 #include "gfxSVGGlyphs.h"
 #include "nsIContent.h" // for GetContent
 #include "nsStubMutationObserver.h"
 #include "nsSVGPaintServerFrame.h"
 
+class gfxContext;
 class nsDisplaySVGText;
-class nsRenderingContext;
 class SVGTextFrame;
 class nsTextFrame;
 
 typedef nsSVGDisplayContainerFrame SVGTextFrameBase;
 
 namespace mozilla {
 
 class CharIterator;
@@ -319,17 +319,17 @@ public:
    */
   virtual void FindCloserFrameForSelection(nsPoint aPoint,
                                           FrameWithDistance* aCurrentBestFrame) MOZ_OVERRIDE;
 
 
 
   // nsISVGChildFrame interface:
   virtual void NotifySVGChanged(uint32_t aFlags) MOZ_OVERRIDE;
-  virtual nsresult PaintSVG(nsRenderingContext* aContext,
+  virtual nsresult PaintSVG(gfxContext& aContext,
                             const gfxMatrix& aTransform,
                             const nsIntRect* aDirtyRect = nullptr) MOZ_OVERRIDE;
   virtual nsIFrame* GetFrameForPoint(const gfxPoint& aPoint) MOZ_OVERRIDE;
   virtual void ReflowSVG() MOZ_OVERRIDE;
   virtual nsRect GetCoveredRegion() MOZ_OVERRIDE;
   virtual SVGBBox GetBBoxContribution(const Matrix& aToBBoxUserspace,
                                       uint32_t aFlags) MOZ_OVERRIDE;
 
--- a/layout/svg/nsISVGChildFrame.h
+++ b/layout/svg/nsISVGChildFrame.h
@@ -4,19 +4,19 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef __NS_ISVGCHILDFRAME_H__
 #define __NS_ISVGCHILDFRAME_H__
 
 #include "gfxRect.h"
 #include "nsQueryFrame.h"
 
+class gfxContext;
 class gfxMatrix;
 class nsIFrame;
-class nsRenderingContext;
 class SVGBBox;
 
 struct nsPoint;
 struct nsRect;
 struct nsIntRect;
 
 namespace mozilla {
 class SVGAnimatedLengthList;
@@ -70,17 +70,17 @@ public:
    *   the DrawTarget when possible and instead just pass a transform down to
    *   their children.  This is preferable because changing the transform is
    *   very expensive for certain DrawTarget backends so it is best to minimize
    *   the number of transform changes.
    *
    * @param aDirtyRect The area being redrawn, in frame offset pixel
    *   coordinates.
    */
-  virtual nsresult PaintSVG(nsRenderingContext* aContext,
+  virtual nsresult PaintSVG(gfxContext& aContext,
                             const gfxMatrix& aTransform,
                             const nsIntRect* aDirtyRect = nullptr) = 0;
 
   /**
    * Returns the frame that should handle pointer events at aPoint.  aPoint is
    * expected to be in the SVG user space of the frame on which this method is
    * called.  The frame returned may be the frame on which this method is
    * called, any of its descendants or else nullptr.
--- a/layout/svg/nsSVGClipPathFrame.cpp
+++ b/layout/svg/nsSVGClipPathFrame.cpp
@@ -5,17 +5,16 @@
 
 // Main header first:
 #include "nsSVGClipPathFrame.h"
 
 // Keep others in (case-insensitive) order:
 #include "gfxContext.h"
 #include "mozilla/dom/SVGClipPathElement.h"
 #include "nsGkAtoms.h"
-#include "nsRenderingContext.h"
 #include "nsSVGEffects.h"
 #include "nsSVGPathGeometryElement.h"
 #include "nsSVGPathGeometryFrame.h"
 #include "nsSVGUtils.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::gfx;
@@ -95,18 +94,16 @@ nsSVGClipPathFrame::ApplyClipOrPaintClip
     aContext.Save();
     if (referencedClipIsTrivial) {
       clipPathFrame->ApplyClipOrPaintClipMask(aContext, aClippedFrame, aMatrix);
     } else {
       aContext.PushGroup(gfxContentType::ALPHA);
     }
   }
 
-  nsRenderingContext rendCtx(&aContext);
-
   for (nsIFrame* kid = mFrames.FirstChild(); kid;
        kid = kid->GetNextSibling()) {
     nsISVGChildFrame* SVGFrame = do_QueryFrame(kid);
     if (SVGFrame) {
       // The CTM of each frame referencing us can be different.
       SVGFrame->NotifySVGChanged(nsISVGChildFrame::TRANSFORM_CHANGED);
 
       bool isOK = true;
@@ -132,17 +129,17 @@ nsSVGClipPathFrame::ApplyClipOrPaintClip
       nsIFrame* child = do_QueryFrame(SVGFrame);
       nsIContent* childContent = child->GetContent();
       if (childContent->IsSVG()) {
         toChildsUserSpace =
           static_cast<const nsSVGElement*>(childContent)->
             PrependLocalTransformsTo(mMatrixForChildren,
                                      nsSVGElement::eUserSpaceToParent);
       }
-      SVGFrame->PaintSVG(&rendCtx, toChildsUserSpace);
+      SVGFrame->PaintSVG(aContext, toChildsUserSpace);
 
       if (clipPathFrame) {
         if (!isTrivial) {
           aContext.PopGroupToSource();
 
           aContext.PushGroup(gfxContentType::ALPHA);
 
           clipPathFrame->ApplyClipOrPaintClipMask(aContext, aClippedFrame, aMatrix);
--- a/layout/svg/nsSVGContainerFrame.cpp
+++ b/layout/svg/nsSVGContainerFrame.cpp
@@ -243,17 +243,17 @@ nsSVGDisplayContainerFrame::IsSVGTransfo
   }
   return foundTransform;
 }
 
 //----------------------------------------------------------------------
 // nsISVGChildFrame methods
 
 nsresult
-nsSVGDisplayContainerFrame::PaintSVG(nsRenderingContext* aContext,
+nsSVGDisplayContainerFrame::PaintSVG(gfxContext& aContext,
                                      const gfxMatrix& aTransform,
                                      const nsIntRect *aDirtyRect)
 {
   NS_ASSERTION(!NS_SVGDisplayListPaintingEnabled() ||
                (mState & NS_FRAME_IS_NONDISPLAY) ||
                PresContext()->IsGlyph(),
                "If display lists are enabled, only painting of non-display "
                "SVG should take this code path");
@@ -285,17 +285,17 @@ nsSVGDisplayContainerFrame::PaintSVG(nsR
         continue; // nothing to paint for kid
       }
       m = element->
             PrependLocalTransformsTo(m, nsSVGElement::eUserSpaceToParent);
       if (m.IsSingular()) {
         continue;
       }
     }
-    nsSVGUtils::PaintFrameWithEffects(kid, *aContext->ThebesContext(), m, aDirtyRect);
+    nsSVGUtils::PaintFrameWithEffects(kid, aContext, m, aDirtyRect);
   }
 
   return NS_OK;
 }
 
 nsIFrame*
 nsSVGDisplayContainerFrame::GetFrameForPoint(const gfxPoint& aPoint)
 {
--- a/layout/svg/nsSVGContainerFrame.h
+++ b/layout/svg/nsSVGContainerFrame.h
@@ -10,20 +10,20 @@
 #include "nsContainerFrame.h"
 #include "nsFrame.h"
 #include "nsIFrame.h"
 #include "nsISVGChildFrame.h"
 #include "nsQueryFrame.h"
 #include "nsRect.h"
 #include "nsSVGUtils.h"
 
+class gfxContext;
 class nsFrameList;
 class nsIContent;
 class nsIPresShell;
-class nsRenderingContext;
 class nsStyleContext;
 
 struct nsPoint;
 struct nsRect;
 struct nsIntRect;
 
 typedef nsContainerFrame nsSVGContainerFrameBase;
 
@@ -139,17 +139,17 @@ public:
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
 
   virtual bool IsSVGTransformed(Matrix *aOwnTransform = nullptr,
                                 Matrix *aFromParentTransform = nullptr) const MOZ_OVERRIDE;
 
   // nsISVGChildFrame interface:
-  virtual nsresult PaintSVG(nsRenderingContext* aContext,
+  virtual nsresult PaintSVG(gfxContext& aContext,
                             const gfxMatrix& aTransform,
                             const nsIntRect *aDirtyRect = nullptr) MOZ_OVERRIDE;
   virtual nsIFrame* GetFrameForPoint(const gfxPoint& aPoint) MOZ_OVERRIDE;
   virtual nsRect GetCoveredRegion() MOZ_OVERRIDE;
   virtual void ReflowSVG() MOZ_OVERRIDE;
   virtual void NotifySVGChanged(uint32_t aFlags) MOZ_OVERRIDE;
   virtual SVGBBox GetBBoxContribution(const Matrix &aToBBoxUserspace,
                                       uint32_t aFlags) MOZ_OVERRIDE;
--- a/layout/svg/nsSVGForeignObjectFrame.cpp
+++ b/layout/svg/nsSVGForeignObjectFrame.cpp
@@ -187,17 +187,17 @@ nsSVGForeignObjectFrame::IsSVGTransforme
                                   nsSVGElement::eUserSpaceToParent));
     }
     foundTransform = true;
   }
   return foundTransform;
 }
 
 nsresult
-nsSVGForeignObjectFrame::PaintSVG(nsRenderingContext *aContext,
+nsSVGForeignObjectFrame::PaintSVG(gfxContext& aContext,
                                   const gfxMatrix& aTransform,
                                   const nsIntRect* aDirtyRect)
 {
   NS_ASSERTION(!NS_SVGDisplayListPaintingEnabled() ||
                (mState & NS_FRAME_IS_NONDISPLAY),
                "If display lists are enabled, only painting of non-display "
                "SVG should take this code path");
 
@@ -236,48 +236,47 @@ nsSVGForeignObjectFrame::PaintSVG(nsRend
     // XXX after bug 614732 is fixed, we will compare mRect with aDirtyRect,
     // not with kidDirtyRect. I.e.
     // int32_t appUnitsPerDevPx = PresContext()->AppUnitsPerDevPixel();
     // mRect.ToOutsidePixels(appUnitsPerDevPx).Intersects(*aDirtyRect)
     if (kidDirtyRect.IsEmpty())
       return NS_OK;
   }
 
-  gfxContext *gfx = aContext->ThebesContext();
-
-  gfx->Save();
+  aContext.Save();
 
   if (StyleDisplay()->IsScrollableOverflow()) {
     float x, y, width, height;
     static_cast<nsSVGElement*>(mContent)->
       GetAnimatedLengthValues(&x, &y, &width, &height, nullptr);
 
     gfxRect clipRect =
       nsSVGUtils::GetClipRectForFrame(this, 0.0f, 0.0f, width, height);
-    nsSVGUtils::SetClipRect(gfx, aTransform, clipRect);
+    nsSVGUtils::SetClipRect(&aContext, aTransform, clipRect);
   }
 
   // SVG paints in CSS px, but normally frames paint in dev pixels. Here we
   // multiply a CSS-px-to-dev-pixel factor onto aTransform so our children
   // paint correctly.
   float cssPxPerDevPx = PresContext()->
     AppUnitsToFloatCSSPixels(PresContext()->AppUnitsPerDevPixel());
   gfxMatrix canvasTMForChildren = aTransform;
   canvasTMForChildren.Scale(cssPxPerDevPx, cssPxPerDevPx);
 
-  gfx->Multiply(canvasTMForChildren);
+  aContext.Multiply(canvasTMForChildren);
 
   uint32_t flags = nsLayoutUtils::PAINT_IN_TRANSFORM;
-  if (SVGAutoRenderState::IsPaintingToWindow(aContext->GetDrawTarget())) {
+  if (SVGAutoRenderState::IsPaintingToWindow(aContext.GetDrawTarget())) {
     flags |= nsLayoutUtils::PAINT_TO_WINDOW;
   }
-  nsresult rv = nsLayoutUtils::PaintFrame(aContext, kid, nsRegion(kidDirtyRect),
+  nsRenderingContext rendCtx(&aContext);
+  nsresult rv = nsLayoutUtils::PaintFrame(&rendCtx, kid, nsRegion(kidDirtyRect),
                                           NS_RGBA(0,0,0,0), flags);
 
-  gfx->Restore();
+  aContext.Restore();
 
   return rv;
 }
 
 nsIFrame*
 nsSVGForeignObjectFrame::GetFrameForPoint(const gfxPoint& aPoint)
 {
   NS_ASSERTION(!NS_SVGDisplayListHitTestingEnabled() ||
--- a/layout/svg/nsSVGForeignObjectFrame.h
+++ b/layout/svg/nsSVGForeignObjectFrame.h
@@ -8,17 +8,17 @@
 
 #include "mozilla/Attributes.h"
 #include "nsContainerFrame.h"
 #include "nsIPresShell.h"
 #include "nsISVGChildFrame.h"
 #include "nsRegion.h"
 #include "nsSVGUtils.h"
 
-class nsRenderingContext;
+class gfxContext;
 class nsSVGOuterSVGFrame;
 
 typedef nsContainerFrame nsSVGForeignObjectFrameBase;
 
 class nsSVGForeignObjectFrame : public nsSVGForeignObjectFrameBase,
                                 public nsISVGChildFrame
 {
   friend nsContainerFrame*
@@ -71,17 +71,17 @@ public:
 #ifdef DEBUG_FRAME_DUMP
   virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE
   {
     return MakeFrameName(NS_LITERAL_STRING("SVGForeignObject"), aResult);
   }
 #endif
 
   // nsISVGChildFrame interface:
-  virtual nsresult PaintSVG(nsRenderingContext *aContext,
+  virtual nsresult PaintSVG(gfxContext& aContext,
                             const gfxMatrix& aTransform,
                             const nsIntRect* aDirtyRect = nullptr) MOZ_OVERRIDE;
   virtual nsIFrame* GetFrameForPoint(const gfxPoint& aPoint) MOZ_OVERRIDE;
   virtual nsRect GetCoveredRegion() MOZ_OVERRIDE;
   virtual void ReflowSVG() MOZ_OVERRIDE;
   virtual void NotifySVGChanged(uint32_t aFlags) MOZ_OVERRIDE;
   virtual SVGBBox GetBBoxContribution(const Matrix &aToBBoxUserspace,
                                       uint32_t aFlags) MOZ_OVERRIDE;
--- a/layout/svg/nsSVGImageFrame.cpp
+++ b/layout/svg/nsSVGImageFrame.cpp
@@ -57,17 +57,17 @@ protected:
   explicit nsSVGImageFrame(nsStyleContext* aContext) : nsSVGImageFrameBase(aContext),
                                                        mReflowCallbackPosted(false) {}
   virtual ~nsSVGImageFrame();
 
 public:
   NS_DECL_FRAMEARENA_HELPERS
 
   // nsISVGChildFrame interface:
-  virtual nsresult PaintSVG(nsRenderingContext *aContext,
+  virtual nsresult PaintSVG(gfxContext& aContext,
                             const gfxMatrix& aTransform,
                             const nsIntRect* aDirtyRect = nullptr) MOZ_OVERRIDE;
   virtual nsIFrame* GetFrameForPoint(const gfxPoint& aPoint) MOZ_OVERRIDE;
   virtual void ReflowSVG() MOZ_OVERRIDE;
 
   // nsSVGPathGeometryFrame methods:
   virtual uint16_t GetHitTestFlags() MOZ_OVERRIDE;
 
@@ -286,17 +286,17 @@ nsSVGImageFrame::TransformContextForPain
 
   aGfxContext->Multiply(ThebesMatrix(imageTransform));
   return true;
 }
 
 //----------------------------------------------------------------------
 // nsISVGChildFrame methods:
 nsresult
-nsSVGImageFrame::PaintSVG(nsRenderingContext *aContext,
+nsSVGImageFrame::PaintSVG(gfxContext& aContext,
                           const gfxMatrix& aTransform,
                           const nsIntRect *aDirtyRect)
 {
   nsresult rv = NS_OK;
 
   if (!StyleVisibility()->IsVisible())
     return NS_OK;
 
@@ -313,39 +313,38 @@ nsSVGImageFrame::PaintSVG(nsRenderingCon
       imageLoader->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
                               getter_AddRefs(currentRequest));
 
     if (currentRequest)
       currentRequest->GetImage(getter_AddRefs(mImageContainer));
   }
 
   if (mImageContainer) {
-    gfxContext* ctx = aContext->ThebesContext();
-    gfxContextAutoSaveRestore autoRestorer(ctx);
+    gfxContextAutoSaveRestore autoRestorer(&aContext);
 
     if (StyleDisplay()->IsScrollableOverflow()) {
       gfxRect clipRect = nsSVGUtils::GetClipRectForFrame(this, x, y,
                                                          width, height);
-      nsSVGUtils::SetClipRect(ctx, aTransform, clipRect);
+      nsSVGUtils::SetClipRect(&aContext, aTransform, clipRect);
     }
 
-    if (!TransformContextForPainting(ctx, aTransform)) {
+    if (!TransformContextForPainting(&aContext, aTransform)) {
       return NS_ERROR_FAILURE;
     }
 
     // fill-opacity doesn't affect <image>, so if we're allowed to
     // optimize group opacity, the opacity used for compositing the
     // image into the current canvas is just the group opacity.
     float opacity = 1.0f;
     if (nsSVGUtils::CanOptimizeOpacity(this)) {
       opacity = StyleDisplay()->mOpacity;
     }
 
     if (opacity != 1.0f || StyleDisplay()->mMixBlendMode != NS_STYLE_BLEND_NORMAL) {
-      ctx->PushGroup(gfxContentType::COLOR_ALPHA);
+      aContext.PushGroup(gfxContentType::COLOR_ALPHA);
     }
 
     nscoord appUnitsPerDevPx = PresContext()->AppUnitsPerDevPixel();
     nsRect dirtyRect; // only used if aDirtyRect is non-null
     if (aDirtyRect) {
       NS_ASSERTION(!NS_SVGDisplayListPaintingEnabled() ||
                    (mState & NS_FRAME_IS_NONDISPLAY),
                    "Display lists handle dirty rect intersection test");
@@ -358,53 +357,55 @@ nsSVGImageFrame::PaintSVG(nsRenderingCon
     }
 
     // XXXbholley - I don't think huge images in SVGs are common enough to
     // warrant worrying about the responsiveness impact of doing synchronous
     // decodes. The extra code complexity of determinining when we want to
     // force sync probably just isn't worth it, so always pass FLAG_SYNC_DECODE
     uint32_t drawFlags = imgIContainer::FLAG_SYNC_DECODE;
 
+    nsRenderingContext rendCtx(&aContext);
+
     if (mImageContainer->GetType() == imgIContainer::TYPE_VECTOR) {
       // Package up the attributes of this image element which can override the
       // attributes of mImageContainer's internal SVG document.
       SVGImageContext context(nsIntSize(width, height),
                               Some(imgElem->mPreserveAspectRatio.GetAnimValue()));
 
       nsRect destRect(0, 0,
                       appUnitsPerDevPx * width,
                       appUnitsPerDevPx * height);
 
       // Note: Can't use DrawSingleUnscaledImage for the TYPE_VECTOR case.
       // That method needs our image to have a fixed native width & height,
       // and that's not always true for TYPE_VECTOR images.
       nsLayoutUtils::DrawSingleImage(
-        aContext,
+        &rendCtx,
         PresContext(),
         mImageContainer,
         nsLayoutUtils::GetGraphicsFilterForFrame(this),
         destRect,
         aDirtyRect ? dirtyRect : destRect,
         &context,
         drawFlags);
     } else { // mImageContainer->GetType() == TYPE_RASTER
       nsLayoutUtils::DrawSingleUnscaledImage(
-        aContext,
+        &rendCtx,
         PresContext(),
         mImageContainer,
         nsLayoutUtils::GetGraphicsFilterForFrame(this),
         nsPoint(0, 0),
         aDirtyRect ? &dirtyRect : nullptr,
         drawFlags);
     }
 
     if (opacity != 1.0f || StyleDisplay()->mMixBlendMode != NS_STYLE_BLEND_NORMAL) {
-      ctx->PopGroupToSource();
-      ctx->SetOperator(gfxContext::OPERATOR_OVER);
-      ctx->Paint(opacity);
+      aContext.PopGroupToSource();
+      aContext.SetOperator(gfxContext::OPERATOR_OVER);
+      aContext.Paint(opacity);
     }
     // gfxContextAutoSaveRestore goes out of scope & cleans up our gfxContext
   }
 
   return rv;
 }
 
 nsIFrame*
--- a/layout/svg/nsSVGInnerSVGFrame.cpp
+++ b/layout/svg/nsSVGInnerSVGFrame.cpp
@@ -6,17 +6,16 @@
 // Main header first:
 #include "nsSVGInnerSVGFrame.h"
 
 // Keep others in (case-insensitive) order:
 #include "gfx2DGlue.h"
 #include "gfxContext.h"
 #include "nsIFrame.h"
 #include "nsISVGChildFrame.h"
-#include "nsRenderingContext.h"
 #include "nsSVGContainerFrame.h"
 #include "nsSVGEffects.h"
 #include "nsSVGIntegrationUtils.h"
 #include "mozilla/dom/SVGSVGElement.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::gfx;
@@ -55,17 +54,17 @@ nsSVGInnerSVGFrame::GetType() const
 {
   return nsGkAtoms::svgInnerSVGFrame;
 }
 
 //----------------------------------------------------------------------
 // nsISVGChildFrame methods
 
 nsresult
-nsSVGInnerSVGFrame::PaintSVG(nsRenderingContext *aContext,
+nsSVGInnerSVGFrame::PaintSVG(gfxContext& aContext,
                              const gfxMatrix& aTransform,
                              const nsIntRect *aDirtyRect)
 {
   NS_ASSERTION(!NS_SVGDisplayListPaintingEnabled() ||
                (mState & NS_FRAME_IS_NONDISPLAY),
                "If display lists are enabled, only painting of non-display "
                "SVG should take this code path");
 
@@ -75,21 +74,20 @@ nsSVGInnerSVGFrame::PaintSVG(nsRendering
     float x, y, width, height;
     static_cast<SVGSVGElement*>(mContent)->
       GetAnimatedLengthValues(&x, &y, &width, &height, nullptr);
 
     if (width <= 0 || height <= 0) {
       return NS_OK;
     }
 
-    gfxContext *gfx = aContext->ThebesContext();
-    autoSR.SetContext(gfx);
+    autoSR.SetContext(&aContext);
     gfxRect clipRect =
       nsSVGUtils::GetClipRectForFrame(this, x, y, width, height);
-    nsSVGUtils::SetClipRect(gfx, aTransform, clipRect);
+    nsSVGUtils::SetClipRect(&aContext, aTransform, clipRect);
   }
 
   return nsSVGInnerSVGFrameBase::PaintSVG(aContext, aTransform, aDirtyRect);
 }
 
 nsRect
 nsSVGInnerSVGFrame::GetCoveredRegion()
 {
--- a/layout/svg/nsSVGInnerSVGFrame.h
+++ b/layout/svg/nsSVGInnerSVGFrame.h
@@ -5,17 +5,17 @@
 
 #ifndef __NS_SVGINNERSVGFRAME_H__
 #define __NS_SVGINNERSVGFRAME_H__
 
 #include "mozilla/Attributes.h"
 #include "nsSVGContainerFrame.h"
 #include "nsISVGSVGFrame.h"
 
-class nsRenderingContext;
+class gfxContext;
 
 typedef nsSVGDisplayContainerFrame nsSVGInnerSVGFrameBase;
 
 class nsSVGInnerSVGFrame : public nsSVGInnerSVGFrameBase,
                            public nsISVGSVGFrame
 {
   friend nsIFrame*
   NS_NewSVGInnerSVGFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
@@ -48,17 +48,17 @@ public:
   }
 #endif
 
   virtual nsresult  AttributeChanged(int32_t         aNameSpaceID,
                                      nsIAtom*        aAttribute,
                                      int32_t         aModType) MOZ_OVERRIDE;
 
   // nsISVGChildFrame interface:
-  virtual nsresult PaintSVG(nsRenderingContext *aContext,
+  virtual nsresult PaintSVG(gfxContext& aContext,
                             const gfxMatrix& aTransform,
                             const nsIntRect *aDirtyRect = nullptr) MOZ_OVERRIDE;
   virtual nsRect GetCoveredRegion() MOZ_OVERRIDE;
   virtual void ReflowSVG() MOZ_OVERRIDE;
   virtual void NotifySVGChanged(uint32_t aFlags) MOZ_OVERRIDE;
   virtual nsIFrame* GetFrameForPoint(const gfxPoint& aPoint) MOZ_OVERRIDE;
 
   // nsSVGContainerFrame methods:
--- a/layout/svg/nsSVGOuterSVGFrame.cpp
+++ b/layout/svg/nsSVGOuterSVGFrame.cpp
@@ -814,17 +814,17 @@ nsSVGOuterSVGFrame::NotifyViewportOrTran
 
   nsSVGUtils::NotifyChildrenOfSVGChange(GetFirstPrincipalChild(), aFlags);
 }
 
 //----------------------------------------------------------------------
 // nsISVGChildFrame methods:
 
 nsresult
-nsSVGOuterSVGFrame::PaintSVG(nsRenderingContext* aContext,
+nsSVGOuterSVGFrame::PaintSVG(gfxContext& aContext,
                              const gfxMatrix& aTransform,
                              const nsIntRect* aDirtyRect)
 {
   NS_ASSERTION(GetFirstPrincipalChild()->GetType() ==
                  nsGkAtoms::svgOuterSVGAnonChildFrame &&
                !GetFirstPrincipalChild()->GetNextSibling(),
                "We should have a single, anonymous, child");
   nsSVGOuterSVGAnonChildFrame *anonKid =
--- a/layout/svg/nsSVGOuterSVGFrame.h
+++ b/layout/svg/nsSVGOuterSVGFrame.h
@@ -6,16 +6,17 @@
 #ifndef __NS_SVGOUTERSVGFRAME_H__
 #define __NS_SVGOUTERSVGFRAME_H__
 
 #include "mozilla/Attributes.h"
 #include "nsISVGSVGFrame.h"
 #include "nsSVGContainerFrame.h"
 #include "nsRegion.h"
 
+class gfxContext;
 class nsSVGForeignObjectFrame;
 
 ////////////////////////////////////////////////////////////////////////
 // nsSVGOuterSVGFrame class
 
 typedef nsSVGDisplayContainerFrame nsSVGOuterSVGFrameBase;
 
 class nsSVGOuterSVGFrame MOZ_FINAL : public nsSVGOuterSVGFrameBase,
@@ -109,17 +110,17 @@ public:
     // themselves.
     return GetFirstPrincipalChild()->IsSVGTransformed();
   }
 
   // nsISVGSVGFrame interface:
   virtual void NotifyViewportOrTransformChanged(uint32_t aFlags) MOZ_OVERRIDE;
 
   // nsISVGChildFrame methods:
-  virtual nsresult PaintSVG(nsRenderingContext* aContext,
+  virtual nsresult PaintSVG(gfxContext& aContext,
                             const gfxMatrix& aTransform,
                             const nsIntRect* aDirtyRect = nullptr) MOZ_OVERRIDE;
   virtual SVGBBox GetBBoxContribution(const Matrix &aToBBoxUserspace,
                                       uint32_t aFlags) MOZ_OVERRIDE;
 
   // nsSVGContainerFrame methods:
   virtual gfxMatrix GetCanvasTM() MOZ_OVERRIDE;
 
--- a/layout/svg/nsSVGPathGeometryFrame.cpp
+++ b/layout/svg/nsSVGPathGeometryFrame.cpp
@@ -106,17 +106,17 @@ nsDisplaySVGPathGeometry::Paint(nsDispla
   // here.
   nsPoint offset = ToReferenceFrame() - mFrame->GetPosition();
 
   gfxPoint devPixelOffset =
     nsLayoutUtils::PointToGfxPoint(offset, appUnitsPerDevPixel);
 
   gfxMatrix tm = nsSVGIntegrationUtils::GetCSSPxToDevPxMatrix(mFrame) *
                    gfxMatrix::Translation(devPixelOffset);
-  static_cast<nsSVGPathGeometryFrame*>(mFrame)->PaintSVG(aCtx, tm);
+  static_cast<nsSVGPathGeometryFrame*>(mFrame)->PaintSVG(*aCtx->ThebesContext(), tm);
 }
 
 //----------------------------------------------------------------------
 // nsIFrame methods
 
 void
 nsSVGPathGeometryFrame::Init(nsIContent*       aContent,
                              nsContainerFrame* aParent,
@@ -235,46 +235,44 @@ nsSVGPathGeometryFrame::BuildDisplayList
   aLists.Content()->AppendNewToTop(
     new (aBuilder) nsDisplaySVGPathGeometry(aBuilder, this));
 }
 
 //----------------------------------------------------------------------
 // nsISVGChildFrame methods
 
 nsresult
-nsSVGPathGeometryFrame::PaintSVG(nsRenderingContext *aContext,
+nsSVGPathGeometryFrame::PaintSVG(gfxContext& aContext,
                                  const gfxMatrix& aTransform,
                                  const nsIntRect* aDirtyRect)
 {
   if (!StyleVisibility()->IsVisible())
     return NS_OK;
 
-  gfxContext* gfx = aContext->ThebesContext();
-
   // Matrix to the geometry's user space:
   gfxMatrix newMatrix =
-    gfx->CurrentMatrix().PreMultiply(aTransform).NudgeToIntegers();
+    aContext.CurrentMatrix().PreMultiply(aTransform).NudgeToIntegers();
   if (newMatrix.IsSingular()) {
     return NS_OK;
   }
 
   uint32_t paintOrder = StyleSVG()->mPaintOrder;
   if (paintOrder == NS_STYLE_PAINT_ORDER_NORMAL) {
-    Render(gfx, eRenderFill | eRenderStroke, newMatrix);
+    Render(&aContext, eRenderFill | eRenderStroke, newMatrix);
     PaintMarkers(aContext, aTransform);
   } else {
     while (paintOrder) {
       uint32_t component =
         paintOrder & ((1 << NS_STYLE_PAINT_ORDER_BITWIDTH) - 1);
       switch (component) {
         case NS_STYLE_PAINT_ORDER_FILL:
-          Render(gfx, eRenderFill, newMatrix);
+          Render(&aContext, eRenderFill, newMatrix);
           break;
         case NS_STYLE_PAINT_ORDER_STROKE:
-          Render(gfx, eRenderStroke, newMatrix);
+          Render(&aContext, eRenderStroke, newMatrix);
           break;
         case NS_STYLE_PAINT_ORDER_MARKERS:
           PaintMarkers(aContext, aTransform);
           break;
       }
       paintOrder >>= NS_STYLE_PAINT_ORDER_BITWIDTH;
     }
   }
@@ -800,47 +798,49 @@ nsSVGPathGeometryFrame::Render(gfxContex
       } else {
         drawTarget->Stroke(path, strokePattern, strokeOptions, drawOptions);
       }
     }
   }
 }
 
 void
-nsSVGPathGeometryFrame::PaintMarkers(nsRenderingContext* aContext,
+nsSVGPathGeometryFrame::PaintMarkers(gfxContext& aContext,
                                      const gfxMatrix& aTransform)
 {
   gfxTextContextPaint *contextPaint =
-    (gfxTextContextPaint*)aContext->GetDrawTarget()->GetUserData(&gfxTextContextPaint::sUserDataKey);
+    (gfxTextContextPaint*)aContext.GetDrawTarget()->GetUserData(&gfxTextContextPaint::sUserDataKey);
 
   if (static_cast<nsSVGPathGeometryElement*>(mContent)->IsMarkable()) {
     MarkerProperties properties = GetMarkerProperties(this);
 
     if (properties.MarkersExist()) {
       float strokeWidth = nsSVGUtils::GetStrokeWidth(this, contextPaint);
 
       nsTArray<nsSVGMark> marks;
       static_cast<nsSVGPathGeometryElement*>
                  (mContent)->GetMarkPoints(&marks);
 
       uint32_t num = marks.Length();
       if (num) {
+        nsRenderingContext rendCtx(&aContext);
+
         // These are in the same order as the nsSVGMark::Type constants.
         nsSVGMarkerFrame* markerFrames[] = {
           properties.GetMarkerStartFrame(),
           properties.GetMarkerMidFrame(),
           properties.GetMarkerEndFrame(),
         };
         PR_STATIC_ASSERT(MOZ_ARRAY_LENGTH(markerFrames) == nsSVGMark::eTypeCount);
 
         for (uint32_t i = 0; i < num; i++) {
           nsSVGMark& mark = marks[i];
           nsSVGMarkerFrame* frame = markerFrames[mark.type];
           if (frame) {
-            frame->PaintMark(aContext, aTransform, this, &mark, strokeWidth);
+            frame->PaintMark(&rendCtx, aTransform, this, &mark, strokeWidth);
           }
         }
       }
     }
   }
 }
 
 uint16_t
--- a/layout/svg/nsSVGPathGeometryFrame.h
+++ b/layout/svg/nsSVGPathGeometryFrame.h
@@ -21,17 +21,16 @@ class DrawTarget;
 }
 }
 
 class gfxContext;
 class nsDisplaySVGPathGeometry;
 class nsIAtom;
 class nsIFrame;
 class nsIPresShell;
-class nsRenderingContext;
 class nsStyleContext;
 class nsSVGMarkerFrame;
 class nsSVGMarkerProperty;
 
 struct nsPoint;
 struct nsRect;
 struct nsIntRect;
 
@@ -95,17 +94,17 @@ public:
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
 
   // nsSVGPathGeometryFrame methods
   gfxMatrix GetCanvasTM();
 protected:
   // nsISVGChildFrame interface:
-  virtual nsresult PaintSVG(nsRenderingContext *aContext,
+  virtual nsresult PaintSVG(gfxContext& aContext,
                             const gfxMatrix& aTransform,
                             const nsIntRect* aDirtyRect = nullptr) MOZ_OVERRIDE;
   virtual nsIFrame* GetFrameForPoint(const gfxPoint& aPoint) MOZ_OVERRIDE;
   virtual nsRect GetCoveredRegion() MOZ_OVERRIDE;
   virtual void ReflowSVG() MOZ_OVERRIDE;
   virtual void NotifySVGChanged(uint32_t aFlags) MOZ_OVERRIDE;
   virtual SVGBBox GetBBoxContribution(const Matrix &aToBBoxUserspace,
                                       uint32_t aFlags) MOZ_OVERRIDE;
@@ -122,17 +121,17 @@ private:
   enum { eRenderFill = 1, eRenderStroke = 2 };
   void Render(gfxContext* aContext, uint32_t aRenderComponents,
               const gfxMatrix& aTransform);
 
   /**
    * @param aMatrix The transform that must be multiplied onto aContext to
    *   establish this frame's SVG user space.
    */
-  void PaintMarkers(nsRenderingContext *aContext, const gfxMatrix& aMatrix);
+  void PaintMarkers(gfxContext& aContext, const gfxMatrix& aMatrix);
 
   struct MarkerProperties {
     nsSVGMarkerProperty* mMarkerStart;
     nsSVGMarkerProperty* mMarkerMid;
     nsSVGMarkerProperty* mMarkerEnd;
 
     bool MarkersExist() const {
       return mMarkerStart || mMarkerMid || mMarkerEnd;
--- a/layout/svg/nsSVGPatternFrame.cpp
+++ b/layout/svg/nsSVGPatternFrame.cpp
@@ -11,17 +11,16 @@
 #include "gfxContext.h"
 #include "gfxMatrix.h"
 #include "gfxPattern.h"
 #include "gfxPlatform.h"
 #include "mozilla/gfx/2D.h"
 #include "nsContentUtils.h"
 #include "nsGkAtoms.h"
 #include "nsISVGChildFrame.h"
-#include "nsRenderingContext.h"
 #include "nsStyleContext.h"
 #include "nsSVGEffects.h"
 #include "nsSVGPathGeometryFrame.h"
 #include "mozilla/dom/SVGPatternElement.h"
 #include "nsSVGUtils.h"
 #include "nsSVGAnimatedTransformList.h"
 #include "SVGContentUtils.h"
 #include "gfxColor.h"
@@ -373,18 +372,17 @@ nsSVGPatternFrame::PaintPattern(const Dr
   }
 
   RefPtr<DrawTarget> dt =
     aDrawTarget->CreateSimilarDrawTarget(surfaceSize, SurfaceFormat::B8G8R8A8);
   if (!dt) {
     return nullptr;
   }
 
-  nsRenderingContext context(dt);
-  gfxContext* gfx = context.ThebesContext();
+  nsRefPtr<gfxContext> gfx = new gfxContext(dt);
 
   // Fill with transparent black
   gfx->SetOperator(gfxContext::OPERATOR_CLEAR);
   gfx->Paint();
   gfx->SetOperator(gfxContext::OPERATOR_OVER);
 
   if (aGraphicOpacity != 1.0f) {
     gfx->Save();
--- a/layout/svg/nsSVGSwitchFrame.cpp
+++ b/layout/svg/nsSVGSwitchFrame.cpp
@@ -5,18 +5,16 @@
 
 // Keep in (case-insensitive) order:
 #include "gfxRect.h"
 #include "nsSVGEffects.h"
 #include "nsSVGGFrame.h"
 #include "mozilla/dom/SVGSwitchElement.h"
 #include "nsSVGUtils.h"
 
-class nsRenderingContext;
-
 using namespace mozilla::gfx;
 
 typedef nsSVGGFrame nsSVGSwitchFrameBase;
 
 class nsSVGSwitchFrame : public nsSVGSwitchFrameBase
 {
   friend nsIFrame*
   NS_NewSVGSwitchFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
@@ -47,17 +45,17 @@ public:
   }
 #endif
 
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
 
   // nsISVGChildFrame interface:
-  virtual nsresult PaintSVG(nsRenderingContext* aContext,
+  virtual nsresult PaintSVG(gfxContext& aContext,
                             const gfxMatrix& aTransform,
                             const nsIntRect* aDirtyRect = nullptr) MOZ_OVERRIDE;
   nsIFrame* GetFrameForPoint(const gfxPoint& aPoint) MOZ_OVERRIDE;
   nsRect GetCoveredRegion() MOZ_OVERRIDE;
   virtual void ReflowSVG() MOZ_OVERRIDE;
   virtual SVGBBox GetBBoxContribution(const Matrix &aToBBoxUserspace,
                                       uint32_t aFlags) MOZ_OVERRIDE;
 
@@ -102,17 +100,17 @@ nsSVGSwitchFrame::BuildDisplayList(nsDis
 {
   nsIFrame* kid = GetActiveChildFrame();
   if (kid) {
     BuildDisplayListForChild(aBuilder, kid, aDirtyRect, aLists);
   }
 }
 
 nsresult
-nsSVGSwitchFrame::PaintSVG(nsRenderingContext* aContext,
+nsSVGSwitchFrame::PaintSVG(gfxContext& aContext,
                            const gfxMatrix& aTransform,
                            const nsIntRect* aDirtyRect)
 {
   NS_ASSERTION(!NS_SVGDisplayListPaintingEnabled() ||
                (mState & NS_FRAME_IS_NONDISPLAY),
                "If display lists are enabled, only painting of non-display "
                "SVG should take this code path");
 
@@ -121,17 +119,17 @@ nsSVGSwitchFrame::PaintSVG(nsRenderingCo
 
   nsIFrame *kid = GetActiveChildFrame();
   if (kid) {
     gfxMatrix tm = aTransform;
     if (kid->GetContent()->IsSVG()) {
       tm = static_cast<nsSVGElement*>(kid->GetContent())->
              PrependLocalTransformsTo(tm, nsSVGElement::eUserSpaceToParent);
     }
-    nsSVGUtils::PaintFrameWithEffects(kid, *aContext->ThebesContext(), tm, aDirtyRect);
+    nsSVGUtils::PaintFrameWithEffects(kid, aContext, tm, aDirtyRect);
   }
   return NS_OK;
 }
 
 
 nsIFrame*
 nsSVGSwitchFrame::GetFrameForPoint(const gfxPoint& aPoint)
 {
--- a/layout/svg/nsSVGUtils.cpp
+++ b/layout/svg/nsSVGUtils.cpp
@@ -461,17 +461,17 @@ public:
       gfxRect dirtyBounds = userToDeviceSpace.TransformBounds(
         gfxRect(aDirtyRect->x, aDirtyRect->y, aDirtyRect->width, aDirtyRect->height));
       dirtyBounds.RoundOut();
       if (gfxUtils::GfxRectToIntRect(dirtyBounds, &tmpDirtyRect)) {
         dirtyRect = &tmpDirtyRect;
       }
     }
 
-    svgChildFrame->PaintSVG(aContext, aTransform, dirtyRect);
+    svgChildFrame->PaintSVG(*aContext->ThebesContext(), aTransform, dirtyRect);
   }
 };
 
 void
 nsSVGUtils::PaintFrameWithEffects(nsIFrame *aFrame,
                                   gfxContext& aContext,
                                   const gfxMatrix& aTransform,
                                   const nsIntRect *aDirtyRect)
@@ -598,18 +598,16 @@ nsSVGUtils::PaintFrameWithEffects(nsIFra
   /* If this frame has only a trivial clipPath, set up cairo's clipping now so
    * we can just do normal painting and get it clipped appropriately.
    */
   if (clipPathFrame && isTrivialClip) {
     aContext.Save();
     clipPathFrame->ApplyClipOrPaintClipMask(aContext, aFrame, aTransform);
   }
 
-  nsRenderingContext rendCtx(&aContext);
-
   /* Paint the child */
   if (effectProperties.HasValidFilter()) {
     nsRegion* dirtyRegion = nullptr;
     nsRegion tmpDirtyRegion;
     if (aDirtyRect) {
       // aDirtyRect is in outer-<svg> device pixels, but the filter code needs
       // it in frame space.
       gfxMatrix userToDeviceSpace = GetUserToCanvasTM(aFrame);
@@ -626,17 +624,17 @@ nsSVGUtils::PaintFrameWithEffects(nsIFra
           dirtyBounds, aFrame->PresContext()->AppUnitsPerCSSPixel()) -
         aFrame->GetPosition();
       dirtyRegion = &tmpDirtyRegion;
     }
     SVGPaintCallback paintCallback;
     nsFilterInstance::PaintFilteredFrame(aFrame, aContext, aTransform,
                                          &paintCallback, dirtyRegion);
   } else {
-    svgChildFrame->PaintSVG(&rendCtx, aTransform, aDirtyRect);
+    svgChildFrame->PaintSVG(aContext, aTransform, aDirtyRect);
   }
 
   if (clipPathFrame && isTrivialClip) {
     aContext.Restore();
   }
 
   /* No more effects, we're done. */
   if (!complexEffects)
@@ -1585,26 +1583,24 @@ nsSVGUtils::PaintSVGGlyph(Element* aElem
 {
   nsIFrame* frame = aElement->GetPrimaryFrame();
   nsISVGChildFrame* svgFrame = do_QueryFrame(frame);
   if (!svgFrame) {
     return false;
   }
   aContext->GetDrawTarget()->AddUserData(&gfxTextContextPaint::sUserDataKey,
                                          aContextPaint, nullptr);
-  nsRenderingContext context(aContext);
-  svgFrame->NotifySVGChanged(nsISVGChildFrame::TRANSFORM_CHANGED);
   gfxMatrix m;
   if (frame->GetContent()->IsSVG()) {
     // PaintSVG() expects the passed transform to be the transform to its own
     // SVG user space, so we need to account for any 'transform' attribute:
     m = static_cast<nsSVGElement*>(frame->GetContent())->
           PrependLocalTransformsTo(gfxMatrix(), nsSVGElement::eUserSpaceToParent);
   }
-  nsresult rv = svgFrame->PaintSVG(&context, m);
+  nsresult rv = svgFrame->PaintSVG(*aContext, m);
   return NS_SUCCEEDED(rv);
 }
 
 bool
 nsSVGUtils::GetSVGGlyphExtents(Element* aElement,
                                const gfxMatrix& aSVGToAppSpace,
                                gfxRect* aResult)
 {