Backed out changeset 836d16519edf (bug 1345853) for frequently failing its own test pattern-big-image.html. r=backout
authorSebastian Hengst <archaeopteryx@coole-files.de>
Fri, 17 Mar 2017 21:54:01 +0100
changeset 398729 dbabc189256eac2eb15147968632164bb5d33ecc
parent 398728 5728195b4bc15492b515f84bc35fde004fc5af2b
child 398730 9aa2aa7a42d2adb1ca2bfebd96d1beb44ef54225
push id1490
push usermtabara@mozilla.com
push dateMon, 31 Jul 2017 14:08:16 +0000
treeherdermozilla-release@70e32e6bf15e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbackout
bugs1345853
milestone55.0a1
backs out836d16519edf994ecf98ef5791f23bc088d99fe4
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
Backed out changeset 836d16519edf (bug 1345853) for frequently failing its own test pattern-big-image.html. r=backout
gfx/thebes/gfxFont.cpp
gfx/thebes/gfxSVGGlyphs.h
layout/svg/SVGContextPaint.cpp
layout/svg/SVGContextPaint.h
layout/svg/SVGGeometryFrame.cpp
layout/svg/SVGGeometryFrame.h
layout/svg/SVGTextFrame.cpp
layout/svg/nsFilterInstance.cpp
layout/svg/nsSVGGradientFrame.cpp
layout/svg/nsSVGGradientFrame.h
layout/svg/nsSVGIntegrationUtils.cpp
layout/svg/nsSVGMaskFrame.cpp
layout/svg/nsSVGPaintServerFrame.h
layout/svg/nsSVGPatternFrame.cpp
layout/svg/nsSVGPatternFrame.h
layout/svg/nsSVGUtils.cpp
layout/svg/nsSVGUtils.h
--- a/gfx/thebes/gfxFont.cpp
+++ b/gfx/thebes/gfxFont.cpp
@@ -1618,26 +1618,20 @@ private:
         buf.mNumGlyphs = mNumGlyphs;
 
         gfxContext::AzureState state = mRunParams.context->CurrentState();
         if (mRunParams.drawMode & DrawMode::GLYPH_FILL) {
             if (state.pattern || mFontParams.contextPaint) {
                 Pattern *pat;
 
                 RefPtr<gfxPattern> fillPattern;
-                if (mFontParams.contextPaint) {
-                  mozilla::image::DrawResult result = mozilla::image::DrawResult::SUCCESS;
-                  Tie(result, fillPattern) =
-                    mFontParams.contextPaint->GetFillPattern(
-                                          mRunParams.context->GetDrawTarget(),
-                                          mRunParams.context->CurrentMatrix());
-                  // XXX cku Flush should return result to the caller?
-                  Unused << result;
-                }
-                if (!fillPattern) {
+                if (!mFontParams.contextPaint ||
+                    !(fillPattern = mFontParams.contextPaint->GetFillPattern(
+                                        mRunParams.context->GetDrawTarget(),
+                                        mRunParams.context->CurrentMatrix()))) {
                     if (state.pattern) {
                         pat = state.pattern->GetPattern(mRunParams.dt,
                                       state.patternTransformChanged ?
                                           &state.patternTransform : nullptr);
                     } else {
                         pat = nullptr;
                     }
                 } else {
--- a/gfx/thebes/gfxSVGGlyphs.h
+++ b/gfx/thebes/gfxSVGGlyphs.h
@@ -197,36 +197,34 @@ public:
                           const gfxMatrix& aCTM) :
         mFillPattern(aFillPattern ? aFillPattern : new gfxPattern(sZero)),
         mStrokePattern(aStrokePattern ? aStrokePattern : new gfxPattern(sZero))
     {
         mFillMatrix = SetupDeviceToPatternMatrix(aFillPattern, aCTM);
         mStrokeMatrix = SetupDeviceToPatternMatrix(aStrokePattern, aCTM);
     }
 
-    mozilla::Pair<DrawResult, RefPtr<gfxPattern>>
-    GetFillPattern(const DrawTarget* aDrawTarget,
-                   float aOpacity,
-                   const gfxMatrix& aCTM) {
+    already_AddRefed<gfxPattern> GetFillPattern(const DrawTarget* aDrawTarget,
+                                                float aOpacity,
+                                                const gfxMatrix& aCTM) {
         if (mFillPattern) {
             mFillPattern->SetMatrix(aCTM * mFillMatrix);
         }
         RefPtr<gfxPattern> fillPattern = mFillPattern;
-        return MakePair(DrawResult::SUCCESS, Move(fillPattern));
+        return fillPattern.forget();
     }
 
-    mozilla::Pair<DrawResult, RefPtr<gfxPattern>>
-    GetStrokePattern(const DrawTarget* aDrawTarget,
-                     float aOpacity,
-                     const gfxMatrix& aCTM) {
+    already_AddRefed<gfxPattern> GetStrokePattern(const DrawTarget* aDrawTarget,
+                                                  float aOpacity,
+                                                  const gfxMatrix& aCTM) {
         if (mStrokePattern) {
             mStrokePattern->SetMatrix(aCTM * mStrokeMatrix);
         }
         RefPtr<gfxPattern> strokePattern = mStrokePattern;
-        return MakePair(DrawResult::SUCCESS, Move(strokePattern));
+        return strokePattern.forget();
     }
 
     float GetFillOpacity() const {
         return mFillPattern ? 1.0f : 0.0f;
     }
 
     float GetStrokeOpacity() const {
         return mStrokePattern ? 1.0f : 0.0f;
--- a/layout/svg/SVGContextPaint.cpp
+++ b/layout/svg/SVGContextPaint.cpp
@@ -8,134 +8,123 @@
 #include "gfxUtils.h"
 #include "mozilla/gfx/2D.h"
 #include "nsIDocument.h"
 #include "nsSVGPaintServerFrame.h"
 #include "nsSVGEffects.h"
 #include "nsSVGPaintServerFrame.h"
 
 using namespace mozilla::gfx;
-using namespace mozilla::image;
 
 namespace mozilla {
 
 /**
  * Stores in |aTargetPaint| information on how to reconstruct the current
  * fill or stroke pattern. Will also set the paint opacity to transparent if
  * the paint is set to "none".
  * @param aOuterContextPaint pattern information from the outer text context
  * @param aTargetPaint where to store the current pattern information
  * @param aFillOrStroke member pointer to the paint we are setting up
  * @param aProperty the frame property descriptor of the fill or stroke paint
  *   server frame
  */
-static DrawResult
+static void
 SetupInheritablePaint(const DrawTarget* aDrawTarget,
                       const gfxMatrix& aContextMatrix,
                       nsIFrame* aFrame,
                       float& aOpacity,
                       SVGContextPaint* aOuterContextPaint,
                       SVGContextPaintImpl::Paint& aTargetPaint,
                       nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
                       nsSVGEffects::PaintingPropertyDescriptor aProperty)
 {
   const nsStyleSVG *style = aFrame->StyleSVG();
   nsSVGPaintServerFrame *ps =
     nsSVGEffects::GetPaintServer(aFrame, aFillOrStroke, aProperty);
 
-  DrawResult result = DrawResult::SUCCESS;
   if (ps) {
-    RefPtr<gfxPattern> pattern;
-    Tie(result, pattern) =
+    RefPtr<gfxPattern> pattern =
       ps->GetPaintServerPattern(aFrame, aDrawTarget, aContextMatrix,
                                 aFillOrStroke, aOpacity);
-
     if (pattern) {
       aTargetPaint.SetPaintServer(aFrame, aContextMatrix, ps);
-      return result;
+      return;
     }
   }
-
   if (aOuterContextPaint) {
     RefPtr<gfxPattern> pattern;
     switch ((style->*aFillOrStroke).Type()) {
     case eStyleSVGPaintType_ContextFill:
-      Tie(result, pattern) =
-        aOuterContextPaint->GetFillPattern(aDrawTarget, aOpacity,
-                                           aContextMatrix);
+      pattern = aOuterContextPaint->GetFillPattern(aDrawTarget, aOpacity,
+                                                   aContextMatrix);
       break;
     case eStyleSVGPaintType_ContextStroke:
-       Tie(result, pattern) =
-         aOuterContextPaint->GetStrokePattern(aDrawTarget, aOpacity,
-                                              aContextMatrix);
+      pattern = aOuterContextPaint->GetStrokePattern(aDrawTarget, aOpacity,
+                                                     aContextMatrix);
       break;
     default:
       ;
     }
     if (pattern) {
       aTargetPaint.SetContextPaint(aOuterContextPaint, (style->*aFillOrStroke).Type());
-      return result;
+      return;
     }
   }
-
   nscolor color =
     nsSVGUtils::GetFallbackOrPaintColor(aFrame->StyleContext(), aFillOrStroke);
   aTargetPaint.SetColor(color);
-
-  return result;
 }
 
-mozilla::Pair<DrawResult, DrawMode>
+DrawMode
 SVGContextPaintImpl::Init(const DrawTarget* aDrawTarget,
                           const gfxMatrix& aContextMatrix,
                           nsIFrame* aFrame,
                           SVGContextPaint* aOuterContextPaint)
 {
   DrawMode toDraw = DrawMode(0);
 
   const nsStyleSVG *style = aFrame->StyleSVG();
-  DrawResult result = DrawResult::SUCCESS;
 
   // fill:
   if (style->mFill.Type() == eStyleSVGPaintType_None) {
     SetFillOpacity(0.0f);
   } else {
     float opacity = nsSVGUtils::GetOpacity(style->FillOpacitySource(),
                                            style->mFillOpacity,
                                            aOuterContextPaint);
 
-    result &= SetupInheritablePaint(aDrawTarget, aContextMatrix, aFrame,
-                                    opacity, aOuterContextPaint,
-                                    mFillPaint, &nsStyleSVG::mFill,
-                                    nsSVGEffects::FillProperty());
+    SetupInheritablePaint(aDrawTarget, aContextMatrix, aFrame,
+                          opacity, aOuterContextPaint,
+                          mFillPaint, &nsStyleSVG::mFill,
+                          nsSVGEffects::FillProperty());
 
     SetFillOpacity(opacity);
 
     toDraw |= DrawMode::GLYPH_FILL;
   }
 
   // stroke:
   if (style->mStroke.Type() == eStyleSVGPaintType_None) {
     SetStrokeOpacity(0.0f);
   } else {
     float opacity = nsSVGUtils::GetOpacity(style->StrokeOpacitySource(),
                                            style->mStrokeOpacity,
                                            aOuterContextPaint);
 
-    result &= SetupInheritablePaint(aDrawTarget, aContextMatrix, aFrame,
-                                    opacity, aOuterContextPaint,
-                                    mStrokePaint, &nsStyleSVG::mStroke,
-                                    nsSVGEffects::StrokeProperty());
+    SetupInheritablePaint(aDrawTarget, aContextMatrix, aFrame,
+                          opacity, aOuterContextPaint,
+                          mStrokePaint, &nsStyleSVG::mStroke,
+                          nsSVGEffects::StrokeProperty());
 
     SetStrokeOpacity(opacity);
 
     toDraw |= DrawMode::GLYPH_STROKE;
   }
 
-  return MakePair(result, toDraw);
+  return toDraw;
 }
 
 void
 SVGContextPaint::InitStrokeGeometry(gfxContext* aContext,
                                     float devUnitsPerSVGUnit)
 {
   mStrokeWidth = aContext->CurrentLineWidth() / devUnitsPerSVGUnit;
   aContext->CurrentDash(mDashes, &mDashOffset);
@@ -164,100 +153,96 @@ SVGContextPaint::GetContextPaint(nsICont
   // bit of a headache so for now we punt on that, don't reapply the constness
   // to the SVGContextPaint here, and trust that no one will add code that
   // actually modifies the object.
 
   return static_cast<SVGContextPaint*>(
            ownerDoc->GetProperty(nsGkAtoms::svgContextPaint));
 }
 
-mozilla::Pair<DrawResult, RefPtr<gfxPattern>>
+already_AddRefed<gfxPattern>
 SVGContextPaintImpl::GetFillPattern(const DrawTarget* aDrawTarget,
                                     float aOpacity,
                                     const gfxMatrix& aCTM)
 {
   return mFillPaint.GetPattern(aDrawTarget, aOpacity, &nsStyleSVG::mFill, aCTM);
 }
 
-mozilla::Pair<DrawResult, RefPtr<gfxPattern>>
+already_AddRefed<gfxPattern>
 SVGContextPaintImpl::GetStrokePattern(const DrawTarget* aDrawTarget,
                                       float aOpacity,
                                       const gfxMatrix& aCTM)
 {
   return mStrokePaint.GetPattern(aDrawTarget, aOpacity, &nsStyleSVG::mStroke, aCTM);
 }
 
-mozilla::Pair<DrawResult, RefPtr<gfxPattern>>
+already_AddRefed<gfxPattern>
 SVGContextPaintImpl::Paint::GetPattern(const DrawTarget* aDrawTarget,
                                        float aOpacity,
                                        nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
                                        const gfxMatrix& aCTM)
 {
   RefPtr<gfxPattern> pattern;
   if (mPatternCache.Get(aOpacity, getter_AddRefs(pattern))) {
     // Set the pattern matrix just in case it was messed with by a previous
     // caller. We should get the same matrix each time a pattern is constructed
     // so this should be fine.
     pattern->SetMatrix(aCTM * mPatternMatrix);
-    return MakePair(DrawResult::SUCCESS, Move(pattern));
+    return pattern.forget();
   }
 
-  DrawResult result = DrawResult::SUCCESS;
   switch (mPaintType) {
   case eStyleSVGPaintType_None:
     pattern = new gfxPattern(Color());
     mPatternMatrix = gfxMatrix();
     break;
   case eStyleSVGPaintType_Color: {
     Color color = Color::FromABGR(mPaintDefinition.mColor);
     color.a *= aOpacity;
     pattern = new gfxPattern(color);
     mPatternMatrix = gfxMatrix();
     break;
   }
   case eStyleSVGPaintType_Server:
-    Tie(result, pattern) =
-      mPaintDefinition.mPaintServerFrame->GetPaintServerPattern(mFrame,
-                                                                aDrawTarget,
-                                                                mContextMatrix,
-                                                                aFillOrStroke,
-                                                                aOpacity);
+    pattern = mPaintDefinition.mPaintServerFrame->GetPaintServerPattern(mFrame,
+                                                                        aDrawTarget,
+                                                                        mContextMatrix,
+                                                                        aFillOrStroke,
+                                                                        aOpacity);
     {
       // m maps original-user-space to pattern space
       gfxMatrix m = pattern->GetMatrix();
       gfxMatrix deviceToOriginalUserSpace = mContextMatrix;
       if (!deviceToOriginalUserSpace.Invert()) {
-        return MakePair(DrawResult::SUCCESS, RefPtr<gfxPattern>());
+        return nullptr;
       }
       // mPatternMatrix maps device space to pattern space via original user space
       mPatternMatrix = deviceToOriginalUserSpace * m;
     }
     pattern->SetMatrix(aCTM * mPatternMatrix);
     break;
   case eStyleSVGPaintType_ContextFill:
-    Tie(result, pattern) =
-      mPaintDefinition.mContextPaint->GetFillPattern(aDrawTarget,
+    pattern = mPaintDefinition.mContextPaint->GetFillPattern(aDrawTarget,
                                                              aOpacity, aCTM);
     // Don't cache this. mContextPaint will have cached it anyway. If we
     // cache it, we'll have to compute mPatternMatrix, which is annoying.
-    return MakePair(result, Move(pattern));
+    return pattern.forget();
   case eStyleSVGPaintType_ContextStroke:
-    Tie(result, pattern) =
-      mPaintDefinition.mContextPaint->GetStrokePattern(aDrawTarget,
+    pattern = mPaintDefinition.mContextPaint->GetStrokePattern(aDrawTarget,
                                                                aOpacity, aCTM);
     // Don't cache this. mContextPaint will have cached it anyway. If we
     // cache it, we'll have to compute mPatternMatrix, which is annoying.
-    return MakePair(result, Move(pattern));
+    return pattern.forget();
   default:
     MOZ_ASSERT(false, "invalid paint type");
-    return MakePair(DrawResult::SUCCESS, RefPtr<gfxPattern>());
+    return nullptr;
   }
 
   mPatternCache.Put(aOpacity, pattern);
-  return MakePair(result, Move(pattern));
+  return pattern.forget();
 }
 
 AutoSetRestoreSVGContextPaint::AutoSetRestoreSVGContextPaint(
                                  const SVGContextPaint* aContextPaint,
                                  nsIDocument* aSVGDocument)
   : mSVGDocument(aSVGDocument)
   , mOuterContextPaint(aSVGDocument->GetProperty(nsGkAtoms::svgContextPaint))
 {
--- a/layout/svg/SVGContextPaint.h
+++ b/layout/svg/SVGContextPaint.h
@@ -11,17 +11,16 @@
 #include "gfxPattern.h"
 #include "gfxTypes.h"
 #include "mozilla/AlreadyAddRefed.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/gfx/2D.h"
 #include "nsColor.h"
 #include "nsStyleStruct.h"
 #include "nsTArray.h"
-#include "DrawResult.h"
 
 class gfxContext;
 class nsIDocument;
 class nsSVGPaintServerFrame;
 
 namespace mozilla {
 
 /**
@@ -48,40 +47,36 @@ namespace mozilla {
 class SVGContextPaint : public RefCounted<SVGContextPaint>
 {
 protected:
   typedef mozilla::gfx::DrawTarget DrawTarget;
 
   SVGContextPaint() {}
 
 public:
-  typedef image::DrawResult DrawResult;
-
   MOZ_DECLARE_REFCOUNTED_TYPENAME(SVGContextPaint)
 
   virtual ~SVGContextPaint() {}
 
-  virtual mozilla::Pair<DrawResult, RefPtr<gfxPattern>>
-  GetFillPattern(const DrawTarget* aDrawTarget,
-                 float aOpacity,
-                 const gfxMatrix& aCTM) = 0;
-  virtual mozilla::Pair<DrawResult, RefPtr<gfxPattern>>
-  GetStrokePattern(const DrawTarget* aDrawTarget,
-                   float aOpacity,
-                   const gfxMatrix& aCTM) = 0;
+  virtual already_AddRefed<gfxPattern> GetFillPattern(const DrawTarget* aDrawTarget,
+                                                      float aOpacity,
+                                                      const gfxMatrix& aCTM) = 0;
+  virtual already_AddRefed<gfxPattern> GetStrokePattern(const DrawTarget* aDrawTarget,
+                                                        float aOpacity,
+                                                        const gfxMatrix& aCTM) = 0;
   virtual float GetFillOpacity() const = 0;
   virtual float GetStrokeOpacity() const = 0;
 
-  mozilla::Pair<DrawResult, RefPtr<gfxPattern>>
-  GetFillPattern(const DrawTarget* aDrawTarget, const gfxMatrix& aCTM) {
+  already_AddRefed<gfxPattern> GetFillPattern(const DrawTarget* aDrawTarget,
+                                              const gfxMatrix& aCTM) {
     return GetFillPattern(aDrawTarget, GetFillOpacity(), aCTM);
   }
 
-  mozilla::Pair<DrawResult, RefPtr<gfxPattern>>
-  GetStrokePattern(const DrawTarget* aDrawTarget, const gfxMatrix& aCTM) {
+  already_AddRefed<gfxPattern> GetStrokePattern(const DrawTarget* aDrawTarget,
+                                                const gfxMatrix& aCTM) {
     return GetStrokePattern(aDrawTarget, GetStrokeOpacity(), aCTM);
   }
 
   static SVGContextPaint* GetContextPaint(nsIContent* aContent);
 
   // XXX This gets the geometry params from the gfxContext.  We should get that
   // information from the actual paint context!
   void InitStrokeGeometry(gfxContext *aContext,
@@ -137,34 +132,28 @@ private:
 /**
  * This class should be flattened into SVGContextPaint once we get rid of the
  * other sub-class (SimpleTextContextPaint).
  */
 struct SVGContextPaintImpl : public SVGContextPaint
 {
 protected:
   typedef mozilla::gfx::DrawTarget DrawTarget;
-
 public:
-  typedef mozilla::image::DrawResult DrawResult;
+  DrawMode Init(const DrawTarget* aDrawTarget,
+                const gfxMatrix& aContextMatrix,
+                nsIFrame* aFrame,
+                SVGContextPaint* aOuterContextPaint);
 
-  mozilla::Pair<DrawResult, DrawMode>
-  Init(const DrawTarget* aDrawTarget,
-       const gfxMatrix& aContextMatrix,
-       nsIFrame* aFrame,
-       SVGContextPaint* aOuterContextPaint);
-
-  mozilla::Pair<DrawResult, RefPtr<gfxPattern>>
-  GetFillPattern(const DrawTarget* aDrawTarget,
-                 float aOpacity,
-                 const gfxMatrix& aCTM) override;
-  mozilla::Pair<DrawResult, RefPtr<gfxPattern>>
-  GetStrokePattern(const DrawTarget* aDrawTarget,
-                   float aOpacity,
-                   const gfxMatrix& aCTM) override;
+  already_AddRefed<gfxPattern> GetFillPattern(const DrawTarget* aDrawTarget,
+                                              float aOpacity,
+                                              const gfxMatrix& aCTM) override;
+  already_AddRefed<gfxPattern> GetStrokePattern(const DrawTarget* aDrawTarget,
+                                                float aOpacity,
+                                                const gfxMatrix& aCTM) override;
 
   void SetFillOpacity(float aOpacity) { mFillOpacity = aOpacity; }
   float GetFillOpacity() const override { return mFillOpacity; }
 
   void SetStrokeOpacity(float aOpacity) { mStrokeOpacity = aOpacity; }
   float GetStrokeOpacity() const override { return mStrokeOpacity; }
 
   struct Paint {
@@ -204,21 +193,20 @@ public:
     // CTM defining the user space for the pattern we will use.
     gfxMatrix mContextMatrix;
     nsStyleSVGPaintType mPaintType;
 
     // Device-space-to-pattern-space
     gfxMatrix mPatternMatrix;
     nsRefPtrHashtable<nsFloatHashKey, gfxPattern> mPatternCache;
 
-    mozilla::Pair<DrawResult, RefPtr<gfxPattern>>
-    GetPattern(const DrawTarget* aDrawTarget,
-               float aOpacity,
-               nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
-               const gfxMatrix& aCTM);
+    already_AddRefed<gfxPattern> GetPattern(const DrawTarget* aDrawTarget,
+                                            float aOpacity,
+                                            nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
+                                            const gfxMatrix& aCTM);
   };
 
   Paint mFillPaint;
   Paint mStrokePaint;
 
   float mFillOpacity;
   float mStrokeOpacity;
 };
@@ -226,39 +214,32 @@ public:
 /**
  * This class is used to pass context paint to an SVG image when an element
  * references that image (e.g. via HTML <img> or SVG <image>, or by referencing
  * it from a CSS property such as 'background-image').  In this case we only
  * support context colors and not paint servers.
  */
 class SVGEmbeddingContextPaint : public SVGContextPaint
 {
-protected:
-  typedef mozilla::image::DrawResult DrawResult;
-
 public:
   SVGEmbeddingContextPaint() {}
 
   void SetFill(nscolor aFill);
   void SetStroke(nscolor aStroke);
 
-  mozilla::Pair<DrawResult, RefPtr<gfxPattern>>
-  GetFillPattern(const DrawTarget* aDrawTarget,
-                 float aOpacity,
-                 const gfxMatrix& aCTM) override {
-    RefPtr<gfxPattern> fill = mFill;
-    return MakePair(DrawResult::SUCCESS, Move(fill));
+  already_AddRefed<gfxPattern> GetFillPattern(const DrawTarget* aDrawTarget,
+                                              float aOpacity,
+                                              const gfxMatrix& aCTM) override {
+    return do_AddRef(mFill);
   }
 
-  mozilla::Pair<DrawResult, RefPtr<gfxPattern>>
-  GetStrokePattern(const DrawTarget* aDrawTarget,
-                   float aOpacity,
-                   const gfxMatrix& aCTM) override {
-    RefPtr<gfxPattern> stroke = mStroke;
-    return MakePair(DrawResult::SUCCESS, Move(stroke));
+  already_AddRefed<gfxPattern> GetStrokePattern(const DrawTarget* aDrawTarget,
+                                                float aOpacity,
+                                                const gfxMatrix& aCTM) override {
+    return do_AddRef(mStroke);
   }
 
   float GetFillOpacity() const override {
     // Always 1.0f since we don't currently allow 'context-fill-opacity'
     return 1.0f;
   };
 
   float GetStrokeOpacity() const override {
--- a/layout/svg/SVGGeometryFrame.cpp
+++ b/layout/svg/SVGGeometryFrame.cpp
@@ -288,41 +288,39 @@ SVGGeometryFrame::PaintSVG(gfxContext& a
   // Matrix to the geometry's user space:
   gfxMatrix newMatrix =
     aContext.CurrentMatrix().PreMultiply(aTransform).NudgeToIntegers();
   if (newMatrix.IsSingular()) {
     return DrawResult::BAD_ARGS;
   }
 
   uint32_t paintOrder = StyleSVG()->mPaintOrder;
-  DrawResult result = DrawResult::SUCCESS;
-
   if (paintOrder == NS_STYLE_PAINT_ORDER_NORMAL) {
-    result = Render(&aContext, 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:
-          result &= Render(&aContext, eRenderFill, newMatrix);
+          Render(&aContext, eRenderFill, newMatrix);
           break;
         case NS_STYLE_PAINT_ORDER_STROKE:
-          result &= Render(&aContext, eRenderStroke, newMatrix);
+          Render(&aContext, eRenderStroke, newMatrix);
           break;
         case NS_STYLE_PAINT_ORDER_MARKERS:
           PaintMarkers(aContext, aTransform);
           break;
       }
       paintOrder >>= NS_STYLE_PAINT_ORDER_BITWIDTH;
     }
   }
 
-  return result;
+  return DrawResult::SUCCESS;
 }
 
 nsIFrame*
 SVGGeometryFrame::GetFrameForPoint(const gfxPoint& aPoint)
 {
   FillRule fillRule;
   uint16_t hitTestFlags;
   if (GetStateBits() & NS_STATE_SVG_CLIPPATH_CHILD) {
@@ -761,17 +759,17 @@ nsSVGMarkerFrame *
 SVGGeometryFrame::MarkerProperties::GetMarkerEndFrame()
 {
   if (!mMarkerEnd)
     return nullptr;
   return static_cast<nsSVGMarkerFrame *>
     (mMarkerEnd->GetReferencedFrame(nsGkAtoms::svgMarkerFrame, nullptr));
 }
 
-DrawResult
+void
 SVGGeometryFrame::Render(gfxContext* aContext,
                          uint32_t aRenderComponents,
                          const gfxMatrix& aNewTransform)
 {
   MOZ_ASSERT(!aNewTransform.IsSingular());
 
   DrawTarget* drawTarget = aContext->GetDrawTarget();
 
@@ -797,38 +795,35 @@ SVGGeometryFrame::Render(gfxContext* aCo
     // We don't complicate this code with GetAsSimplePath since the cost of
     // masking will dwarf Path creation overhead anyway.
     RefPtr<Path> path = element->GetOrBuildPath(*drawTarget, fillRule);
     if (path) {
       ColorPattern white(ToDeviceColor(Color(1.0f, 1.0f, 1.0f, 1.0f)));
       drawTarget->Fill(path, white,
                        DrawOptions(1.0f, CompositionOp::OP_OVER, aaMode));
     }
-    return DrawResult::SUCCESS;
+    return;
   }
 
   SVGGeometryElement::SimplePath simplePath;
   RefPtr<Path> path;
 
   element->GetAsSimplePath(&simplePath);
   if (!simplePath.IsPath()) {
     path = element->GetOrBuildPath(*drawTarget, fillRule);
     if (!path) {
-      return DrawResult::SUCCESS;
+      return;
     }
   }
 
   SVGContextPaint* contextPaint = SVGContextPaint::GetContextPaint(mContent);
-  DrawResult result = DrawResult::SUCCESS;
 
   if (aRenderComponents & eRenderFill) {
     GeneralPattern fillPattern;
-    result = nsSVGUtils::MakeFillPatternFor(this, aContext, &fillPattern,
-                                            contextPaint);
-
+    nsSVGUtils::MakeFillPatternFor(this, aContext, &fillPattern, contextPaint);
     if (fillPattern.GetPattern()) {
       DrawOptions drawOptions(1.0f, CompositionOp::OP_OVER, aaMode);
       if (simplePath.IsRect()) {
         drawTarget->FillRect(simplePath.AsRect(), fillPattern, drawOptions);
       } else if (path) {
         drawTarget->Fill(path, fillPattern, drawOptions);
       }
     }
@@ -839,58 +834,53 @@ SVGGeometryFrame::Render(gfxContext* aCo
     // Account for vector-effect:non-scaling-stroke:
     gfxMatrix userToOuterSVG;
     if (nsSVGUtils::GetNonScalingStrokeTransform(this, &userToOuterSVG)) {
       // A simple Rect can't be transformed with rotate/skew, so let's switch
       // to using a real path:
       if (!path) {
         path = element->GetOrBuildPath(*drawTarget, fillRule);
         if (!path) {
-          return DrawResult::SUCCESS;
+          return;
         }
         simplePath.Reset();
       }
       // We need to transform the path back into the appropriate ancestor
       // coordinate system, and paint it it that coordinate system, in order
       // for non-scaled stroke to paint correctly.
       gfxMatrix outerSVGToUser = userToOuterSVG;
       outerSVGToUser.Invert();
       aContext->Multiply(outerSVGToUser);
       RefPtr<PathBuilder> builder =
         path->TransformedCopyToBuilder(ToMatrix(userToOuterSVG), fillRule);
       path = builder->Finish();
     }
     GeneralPattern strokePattern;
-    result &=
-      nsSVGUtils::MakeStrokePatternFor(this, aContext, &strokePattern,
-                                       contextPaint);
-
+    nsSVGUtils::MakeStrokePatternFor(this, aContext, &strokePattern, contextPaint);
     if (strokePattern.GetPattern()) {
       SVGContentUtils::AutoStrokeOptions strokeOptions;
       SVGContentUtils::GetStrokeOptions(&strokeOptions,
                                         static_cast<nsSVGElement*>(mContent),
                                         StyleContext(), contextPaint);
       // GetStrokeOptions may set the line width to zero as an optimization
       if (strokeOptions.mLineWidth <= 0) {
-        return DrawResult::SUCCESS;
+        return;
       }
       DrawOptions drawOptions(1.0f, CompositionOp::OP_OVER, aaMode);
       if (simplePath.IsRect()) {
         drawTarget->StrokeRect(simplePath.AsRect(), strokePattern,
                                strokeOptions, drawOptions);
       } else if (simplePath.IsLine()) {
         drawTarget->StrokeLine(simplePath.Point1(), simplePath.Point2(),
                                strokePattern, strokeOptions, drawOptions);
       } else {
         drawTarget->Stroke(path, strokePattern, strokeOptions, drawOptions);
       }
     }
   }
-
-  return result;
 }
 
 void
 SVGGeometryFrame::PaintMarkers(gfxContext& aContext,
                                const gfxMatrix& aTransform)
 {
   SVGContextPaint* contextPaint = SVGContextPaint::GetContextPaint(mContent);
 
--- a/layout/svg/SVGGeometryFrame.h
+++ b/layout/svg/SVGGeometryFrame.h
@@ -116,18 +116,18 @@ protected:
    * This function returns a set of bit flags indicating which parts of the
    * element (fill, stroke, bounds) should intercept pointer events. It takes
    * into account the type of element and the value of the 'pointer-events'
    * property on the element.
    */
   virtual uint16_t GetHitTestFlags();
 private:
   enum { eRenderFill = 1, eRenderStroke = 2 };
-  DrawResult Render(gfxContext* aContext, uint32_t aRenderComponents,
-                    const gfxMatrix& aTransform);
+  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(gfxContext& aContext, const gfxMatrix& aMatrix);
 
   struct MarkerProperties {
--- a/layout/svg/SVGTextFrame.cpp
+++ b/layout/svg/SVGTextFrame.cpp
@@ -2924,17 +2924,17 @@ SVGTextDrawPathCallbacks::HandleTextGeom
   }
 }
 
 void
 SVGTextDrawPathCallbacks::MakeFillPattern(GeneralPattern* aOutPattern)
 {
   if (mColor == NS_SAME_AS_FOREGROUND_COLOR ||
       mColor == NS_40PERCENT_FOREGROUND_COLOR) {
-    Unused << nsSVGUtils::MakeFillPatternFor(mFrame, gfx, aOutPattern);
+    nsSVGUtils::MakeFillPatternFor(mFrame, gfx, aOutPattern);
     return;
   }
 
   if (mColor == NS_TRANSPARENT) {
     return;
   }
 
   aOutPattern->InitColorPattern(ToDeviceColor(mColor));
@@ -2995,18 +2995,17 @@ SVGTextDrawPathCallbacks::FillGeometry()
 void
 SVGTextDrawPathCallbacks::StrokeGeometry()
 {
   // We don't paint the stroke when we are filling with a selection color.
   if (mColor == NS_SAME_AS_FOREGROUND_COLOR ||
       mColor == NS_40PERCENT_FOREGROUND_COLOR) {
     if (nsSVGUtils::HasStroke(mFrame, /*aContextPaint*/ nullptr)) {
       GeneralPattern strokePattern;
-      Unused << nsSVGUtils::MakeStrokePatternFor(mFrame, gfx, &strokePattern,
-                                                 /*aContextPaint*/ nullptr);
+      nsSVGUtils::MakeStrokePatternFor(mFrame, gfx, &strokePattern, /*aContextPaint*/ nullptr);
       if (strokePattern.GetPattern()) {
         if (!mFrame->GetParent()->GetContent()->IsSVGElement()) {
           // The cast that follows would be unsafe
           MOZ_ASSERT(false, "Our nsTextFrame's parent's content should be SVG");
           return;
         }
         nsSVGElement* svgOwner =
           static_cast<nsSVGElement*>(mFrame->GetParent()->GetContent());
@@ -3641,35 +3640,33 @@ SVGTextFrame::PaintSVG(gfxContext& aCont
 
   TextRenderedRunIterator it(this, TextRenderedRunIterator::eVisibleFrames);
   TextRenderedRun run = it.Current();
 
   SVGContextPaint* outerContextPaint =
     SVGContextPaint::GetContextPaint(mContent);
 
   nsRenderingContext rendCtx(&aContext);
-  DrawResult finalResult = DrawResult::SUCCESS;
+
   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.
     aContext.SetMatrix(initialMatrix);
 
     RefPtr<SVGContextPaintImpl> contextPaint = new SVGContextPaintImpl();
-    DrawMode drawMode;
-    DrawResult result = DrawResult::SUCCESS;
-    Tie(result, drawMode) = contextPaint->Init(&aDrawTarget,
-                                               aContext.CurrentMatrix(),
-                                               frame, outerContextPaint);
-    finalResult &= result;
+    DrawMode drawMode = contextPaint->Init(&aDrawTarget,
+                                           aContext.CurrentMatrix(),
+                                           frame, outerContextPaint);
+
     if (drawMode & 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, &aContext, outerContextPaint);
     }
 
     // Set up the transform for painting the text frame for the substring
     // indicated by the run.
@@ -3701,17 +3698,17 @@ SVGTextFrame::PaintSVG(gfxContext& aCont
       // caret with, rather than using the color property?
       caret->PaintCaret(aDrawTarget, frame, nsPoint());
       aContext.NewPath();
     }
 
     run = it.Next();
   }
 
-  return finalResult;
+  return DrawResult::SUCCESS;
 }
 
 nsIFrame*
 SVGTextFrame::GetFrameForPoint(const gfxPoint& aPoint)
 {
   NS_ASSERTION(PrincipalChildList().FirstChild(), "must have a child frame");
 
   if (mState & NS_FRAME_IS_NONDISPLAY) {
--- a/layout/svg/nsFilterInstance.cpp
+++ b/layout/svg/nsFilterInstance.cpp
@@ -413,32 +413,31 @@ nsFilterInstance::BuildSourcePaint(Sourc
 
   RefPtr<gfxContext> ctx = gfxContext::CreateOrNull(offscreenDT);
   MOZ_ASSERT(ctx); // already checked the draw target above
   gfxContextAutoSaveRestore saver(ctx);
 
   ctx->SetMatrix(mPaintTransform *
                  gfxMatrix::Translation(-neededRect.TopLeft()));
   GeneralPattern pattern;
-  DrawResult result = DrawResult::SUCCESS;
   if (aSource == &mFillPaint) {
-    result = nsSVGUtils::MakeFillPatternFor(mTargetFrame, ctx, &pattern);
+    nsSVGUtils::MakeFillPatternFor(mTargetFrame, ctx, &pattern);
   } else if (aSource == &mStrokePaint) {
-    result = nsSVGUtils::MakeStrokePatternFor(mTargetFrame, ctx, &pattern);
+    nsSVGUtils::MakeStrokePatternFor(mTargetFrame, ctx, &pattern);
   }
 
   if (pattern.GetPattern()) {
     offscreenDT->FillRect(ToRect(FilterSpaceToUserSpace(ThebesRect(neededRect))),
                           pattern);
   }
 
   aSource->mSourceSurface = offscreenDT->Snapshot();
   aSource->mSurfaceRect = neededRect;
 
-  return result;
+  return DrawResult::SUCCESS;
 }
 
 DrawResult
 nsFilterInstance::BuildSourcePaints()
 {
   if (!mFillPaint.mNeededBounds.IsEmpty()) {
     DrawResult result = BuildSourcePaint(&mFillPaint);
     if (result != DrawResult::SUCCESS) {
--- a/layout/svg/nsSVGGradientFrame.cpp
+++ b/layout/svg/nsSVGGradientFrame.cpp
@@ -202,17 +202,17 @@ static void GetStopInformation(nsIFrame*
   static_cast<SVGStopElement*>(stopContent)->
     GetAnimatedNumberValues(aOffset, nullptr);
 
   *aOffset = mozilla::clamped(*aOffset, 0.0f, 1.0f);
   *aStopColor = aStopFrame->StyleSVGReset()->mStopColor;
   *aStopOpacity = aStopFrame->StyleSVGReset()->mStopOpacity;
 }
 
-mozilla::Pair<DrawResult, RefPtr<gfxPattern>>
+already_AddRefed<gfxPattern>
 nsSVGGradientFrame::GetPaintServerPattern(nsIFrame* aSource,
                                           const DrawTarget* aDrawTarget,
                                           const gfxMatrix& aContextMatrix,
                                           nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
                                           float aGraphicOpacity,
                                           const gfxRect* aOverrideBounds)
 {
   uint16_t gradientUnits = GetGradientUnits();
@@ -230,56 +230,55 @@ nsSVGGradientFrame::GetPaintServerPatter
   GetStopFrames(&stopFrames);
 
   uint32_t nStops = stopFrames.Length();
 
   // SVG specification says that no stops should be treated like
   // the corresponding fill or stroke had "none" specified.
   if (nStops == 0) {
     RefPtr<gfxPattern> pattern = new gfxPattern(Color());
-    return MakePair(DrawResult::SUCCESS, Move(pattern));
+    return pattern.forget();
   }
 
   if (nStops == 1 || GradientVectorLengthIsZero()) {
     // The gradient paints a single colour, using the stop-color of the last
     // gradient step if there are more than one.
     float stopOpacity = stopFrames[nStops-1]->StyleSVGReset()->mStopOpacity;
     nscolor stopColor = stopFrames[nStops-1]->StyleSVGReset()->mStopColor;
 
     Color stopColor2 = Color::FromABGR(stopColor);
     stopColor2.a *= stopOpacity * aGraphicOpacity;
     RefPtr<gfxPattern> pattern = new gfxPattern(stopColor2);
-    return MakePair(DrawResult::SUCCESS, Move(pattern));
+    return pattern.forget();
   }
 
   // Get the transform list (if there is one). We do this after the returns
   // above since this call can be expensive when "gradientUnits" is set to
   // "objectBoundingBox" (since that requiring a GetBBox() call).
   gfxMatrix patternMatrix = GetGradientTransform(aSource, aOverrideBounds);
 
   if (patternMatrix.IsSingular()) {
-    return MakePair(DrawResult::BAD_ARGS, RefPtr<gfxPattern>());
+    return nullptr;
   }
 
   // revert any vector effect transform so that the gradient appears unchanged
   if (aFillOrStroke == &nsStyleSVG::mStroke) {
     gfxMatrix userToOuterSVG;
     if (nsSVGUtils::GetNonScalingStrokeTransform(aSource, &userToOuterSVG)) {
       patternMatrix *= userToOuterSVG;
     }
   }
 
   if (!patternMatrix.Invert()) {
-    return MakePair(DrawResult::BAD_ARGS, RefPtr<gfxPattern>());
+    return nullptr;
   }
 
   RefPtr<gfxPattern> gradient = CreateGradient();
-  if (!gradient || gradient->CairoStatus()) {
-    return MakePair(DrawResult::TEMPORARY_ERROR, RefPtr<gfxPattern>());
-  }
+  if (!gradient || gradient->CairoStatus())
+    return nullptr;
 
   uint16_t aSpread = GetSpreadMethod();
   if (aSpread == SVG_SPREADMETHOD_PAD)
     gradient->SetExtend(ExtendMode::CLAMP);
   else if (aSpread == SVG_SPREADMETHOD_REFLECT)
     gradient->SetExtend(ExtendMode::REFLECT);
   else if (aSpread == SVG_SPREADMETHOD_REPEAT)
     gradient->SetExtend(ExtendMode::REPEAT);
@@ -300,17 +299,17 @@ nsSVGGradientFrame::GetPaintServerPatter
     else
       lastOffset = offset;
 
     Color stopColor2 = Color::FromABGR(stopColor);
     stopColor2.a *= stopOpacity * aGraphicOpacity;
     gradient->AddColorStop(offset, stopColor2);
   }
 
-  return MakePair(DrawResult::SUCCESS, Move(gradient));
+  return gradient.forget();
 }
 
 // Private (helper) methods
 
 nsSVGGradientFrame *
 nsSVGGradientFrame::GetReferencedGradient()
 {
   if (mNoHRefURI)
--- a/layout/svg/nsSVGGradientFrame.h
+++ b/layout/svg/nsSVGGradientFrame.h
@@ -41,17 +41,17 @@ class nsSVGGradientFrame : public nsSVGP
 
 protected:
   explicit nsSVGGradientFrame(nsStyleContext* aContext);
 
 public:
   NS_DECL_ABSTRACT_FRAME(nsSVGGradientFrame)
 
   // nsSVGPaintServerFrame methods:
-  virtual mozilla::Pair<DrawResult, RefPtr<gfxPattern>>
+  virtual already_AddRefed<gfxPattern>
     GetPaintServerPattern(nsIFrame* aSource,
                           const DrawTarget* aDrawTarget,
                           const gfxMatrix& aContextMatrix,
                           nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
                           float aGraphicOpacity,
                           const gfxRect* aOverrideBounds) override;
 
   // nsIFrame interface:
--- a/layout/svg/nsSVGIntegrationUtils.cpp
+++ b/layout/svg/nsSVGIntegrationUtils.cpp
@@ -1225,22 +1225,20 @@ nsSVGIntegrationUtils::DrawableFromPaint
     // frame by default, so aPaintServerSize is the whole target background fill
     // area.
     nsSVGPaintServerFrame* server =
       static_cast<nsSVGPaintServerFrame*>(aFrame);
 
     gfxRect overrideBounds(0, 0,
                            aPaintServerSize.width, aPaintServerSize.height);
     overrideBounds.ScaleInverse(aFrame->PresContext()->AppUnitsPerDevPixel());
-    DrawResult result = DrawResult::SUCCESS;
-    RefPtr<gfxPattern> pattern;
-    Tie(result, pattern) =
-      server->GetPaintServerPattern(aTarget, aDrawTarget,
-                                    aContextMatrix, &nsStyleSVG::mFill, 1.0,
-                                    &overrideBounds);
+    RefPtr<gfxPattern> pattern =
+    server->GetPaintServerPattern(aTarget, aDrawTarget,
+                                  aContextMatrix, &nsStyleSVG::mFill, 1.0,
+                                  &overrideBounds);
 
     if (!pattern)
       return nullptr;
 
     // pattern is now set up to fill aPaintServerSize. But we want it to
     // fill aRenderSize, so we need to add a scaling transform.
     // We couldn't just have set overrideBounds to aRenderSize - it would have
     // worked for gradients, but for patterns it would result in a different
--- a/layout/svg/nsSVGMaskFrame.cpp
+++ b/layout/svg/nsSVGMaskFrame.cpp
@@ -247,31 +247,34 @@ nsSVGMaskFrame::GetMaskForMaskedFrame(Ma
     context->CurrentMatrix() * gfxMatrix::Translation(-maskSurfaceRect.TopLeft());
 
   RefPtr<gfxContext> tmpCtx = gfxContext::CreateOrNull(maskDT);
   MOZ_ASSERT(tmpCtx); // already checked the draw target above
   tmpCtx->SetMatrix(maskSurfaceMatrix);
 
   mMatrixForChildren = GetMaskTransform(aParams.maskedFrame) *
                        aParams.toUserSpace;
-  DrawResult result = DrawResult::SUCCESS;
+  DrawResult result;
 
   for (nsIFrame* kid = mFrames.FirstChild(); kid;
        kid = kid->GetNextSibling()) {
     // The CTM of each frame referencing us can be different
     nsISVGChildFrame* SVGFrame = do_QueryFrame(kid);
     if (SVGFrame) {
       SVGFrame->NotifySVGChanged(nsISVGChildFrame::TRANSFORM_CHANGED);
     }
     gfxMatrix m = mMatrixForChildren;
     if (kid->GetContent()->IsSVGElement()) {
       m = static_cast<nsSVGElement*>(kid->GetContent())->
             PrependLocalTransformsTo(m, eUserSpaceToParent);
     }
-    result &= nsSVGUtils::PaintFrameWithEffects(kid, *tmpCtx, m);
+    result = nsSVGUtils::PaintFrameWithEffects(kid, *tmpCtx, m);
+    if (result != DrawResult::SUCCESS) {
+      return MakePair(result, RefPtr<SourceSurface>());
+    }
   }
 
   RefPtr<SourceSurface> maskSnapshot = maskDT->Snapshot();
   if (!maskSnapshot) {
     return MakePair(DrawResult::TEMPORARY_ERROR, RefPtr<SourceSurface>());
   }
   RefPtr<DataSourceSurface> maskSurface = maskSnapshot->GetDataSurface();
   DataSourceSurface::MappedSurface map;
@@ -320,17 +323,17 @@ nsSVGMaskFrame::GetMaskForMaskedFrame(Ma
 
   // Moz2D transforms in the opposite direction to Thebes
   if (!maskSurfaceMatrix.Invert()) {
     return MakePair(DrawResult::TEMPORARY_ERROR, RefPtr<SourceSurface>());
   }
 
   *aParams.maskTransform = ToMatrix(maskSurfaceMatrix);
   RefPtr<SourceSurface> surface = destMaskSurface.forget();
-  return MakePair(result, Move(surface));
+  return MakePair(DrawResult::SUCCESS, Move(surface));
 }
 
 gfxRect
 nsSVGMaskFrame::GetMaskArea(nsIFrame* aMaskedFrame)
 {
   SVGMaskElement *maskElem = static_cast<SVGMaskElement*>(mContent);
 
   uint16_t units =
--- a/layout/svg/nsSVGPaintServerFrame.h
+++ b/layout/svg/nsSVGPaintServerFrame.h
@@ -25,17 +25,16 @@ class gfxPattern;
 class nsStyleContext;
 
 struct gfxRect;
 
 class nsSVGPaintServerFrame : public nsSVGContainerFrame
 {
 protected:
   typedef mozilla::gfx::DrawTarget DrawTarget;
-  typedef mozilla::image::DrawResult DrawResult;
 
   explicit nsSVGPaintServerFrame(nsStyleContext* aContext)
     : nsSVGContainerFrame(aContext)
   {
     AddStateBits(NS_FRAME_IS_NONDISPLAY);
   }
 
 public:
@@ -44,17 +43,17 @@ public:
   /**
    * Constructs a gfxPattern of the paint server rendering.
    *
    * @param aContextMatrix The transform matrix that is currently applied to
    *   the gfxContext that is being drawn to. This is needed by SVG patterns so
    *   that surfaces of the correct size can be created. (SVG gradients are
    *   vector based, so it's not used there.)
    */
-  virtual mozilla::Pair<DrawResult, RefPtr<gfxPattern>>
+  virtual already_AddRefed<gfxPattern>
     GetPaintServerPattern(nsIFrame *aSource,
                           const DrawTarget* aDrawTarget,
                           const gfxMatrix& aContextMatrix,
                           nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
                           float aOpacity,
                           const gfxRect *aOverrideBounds = nullptr) = 0;
 
   // nsIFrame methods:
--- a/layout/svg/nsSVGPatternFrame.cpp
+++ b/layout/svg/nsSVGPatternFrame.cpp
@@ -225,17 +225,17 @@ GetTargetGeometry(gfxRect *aBBox,
   float scale = MaxExpansion(aContextMatrix);
   if (scale <= 0) {
     return NS_ERROR_FAILURE;
   }
   aBBox->Scale(scale);
   return NS_OK;
 }
 
-mozilla::Pair<DrawResult, RefPtr<SourceSurface>>
+already_AddRefed<SourceSurface>
 nsSVGPatternFrame::PaintPattern(const DrawTarget* aDrawTarget,
                                 Matrix* patternMatrix,
                                 const Matrix &aContextMatrix,
                                 nsIFrame *aSource,
                                 nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
                                 float aGraphicOpacity,
                                 const gfxRect *aOverrideBounds)
 {
@@ -248,18 +248,17 @@ nsSVGPatternFrame::PaintPattern(const Dr
    *    Calculate the content transformation matrix
    *    Get our children (we may need to get them from another Pattern)
    *    Call SVGPaint on all of our children
    *    Return
    */
 
   nsSVGPatternFrame* patternWithChildren = GetPatternWithChildren();
   if (!patternWithChildren) {
-    // Either no kids or a bad reference
-    return MakePair(DrawResult::SUCCESS, RefPtr<SourceSurface>());
+    return nullptr; // Either no kids or a bad reference
   }
   nsIFrame* firstKid = patternWithChildren->mFrames.FirstChild();
 
   const nsSVGViewBox& viewBox = GetViewBox();
 
   uint16_t patternContentUnits =
     GetEnumValue(SVGPatternElement::PATTERNCONTENTUNITS);
   uint16_t patternUnits =
@@ -288,76 +287,76 @@ nsSVGPatternFrame::PaintPattern(const Dr
   // the geometry that is being rendered with a pattern
   gfxRect callerBBox;
   if (NS_FAILED(GetTargetGeometry(&callerBBox,
                                   viewBox,
                                   patternContentUnits, patternUnits,
                                   aSource,
                                   aContextMatrix,
                                   aOverrideBounds))) {
-    return MakePair(DrawResult::SUCCESS, RefPtr<SourceSurface>());
+    return nullptr;
   }
 
   // Construct the CTM that we will provide to our children when we
   // render them into the tile.
   gfxMatrix ctm = ConstructCTM(viewBox, patternContentUnits, patternUnits,
                                callerBBox, aContextMatrix, aSource);
   if (ctm.IsSingular()) {
-    return MakePair(DrawResult::BAD_ARGS, RefPtr<SourceSurface>());
+    return nullptr;
   }
 
   if (patternWithChildren->mCTM) {
     *patternWithChildren->mCTM = ctm;
   } else {
     patternWithChildren->mCTM = new gfxMatrix(ctm);
   }
 
   // Get the bounding box of the pattern.  This will be used to determine
   // the size of the surface, and will also be used to define the bounding
   // box for the pattern tile.
   gfxRect bbox = GetPatternRect(patternUnits, callerBBox, aContextMatrix, aSource);
   if (bbox.Width() <= 0.0 || bbox.Height() <= 0.0) {
-    return MakePair(DrawResult::SUCCESS, RefPtr<SourceSurface>());
+    return nullptr;
   }
 
   // Get the pattern transform
   Matrix patternTransform = ToMatrix(GetPatternTransform());
 
   // revert the vector effect transform so that the pattern appears unchanged
   if (aFillOrStroke == &nsStyleSVG::mStroke) {
     gfxMatrix userToOuterSVG;
     if (nsSVGUtils::GetNonScalingStrokeTransform(aSource, &userToOuterSVG)) {
       patternTransform *= ToMatrix(userToOuterSVG);
       if (patternTransform.IsSingular()) {
         NS_WARNING("Singular matrix painting non-scaling-stroke");
-        return MakePair(DrawResult::BAD_ARGS, RefPtr<SourceSurface>());
+        return nullptr;
       }
     }
   }
 
   // Get the transformation matrix that we will hand to the renderer's pattern
   // routine.
   *patternMatrix = GetPatternMatrix(patternUnits, patternTransform,
                                     bbox, callerBBox, aContextMatrix);
   if (patternMatrix->IsSingular()) {
-    return MakePair(DrawResult::BAD_ARGS, RefPtr<SourceSurface>());
+    return nullptr;
   }
 
   // Now that we have all of the necessary geometries, we can
   // create our surface.
   gfxRect transformedBBox = ThebesRect(patternTransform.TransformBounds(ToRect(bbox)));
 
   bool resultOverflows;
   IntSize surfaceSize =
     nsSVGUtils::ConvertToSurfaceSize(
       transformedBBox.Size(), &resultOverflows);
 
   // 0 disables rendering, < 0 is an error
   if (surfaceSize.width <= 0 || surfaceSize.height <= 0) {
-    return MakePair(DrawResult::SUCCESS, RefPtr<SourceSurface>());
+    return nullptr;
   }
 
   gfxFloat patternWidth = bbox.Width();
   gfxFloat patternHeight = bbox.Height();
 
   if (resultOverflows ||
       patternWidth != surfaceSize.width ||
       patternHeight != surfaceSize.height) {
@@ -371,17 +370,17 @@ nsSVGPatternFrame::PaintPattern(const Dr
     // and rescale pattern to compensate
     patternMatrix->PreScale(patternWidth / surfaceSize.width,
                             patternHeight / surfaceSize.height);
   }
 
   RefPtr<DrawTarget> dt =
     aDrawTarget->CreateSimilarDrawTarget(surfaceSize, SurfaceFormat::B8G8R8A8);
   if (!dt || !dt->IsValid()) {
-    return MakePair(DrawResult::TEMPORARY_ERROR, RefPtr<SourceSurface>());
+    return nullptr;
   }
   dt->ClearRect(Rect(0, 0, surfaceSize.width, surfaceSize.height));
 
   RefPtr<gfxContext> gfx = gfxContext::CreateOrNull(dt);
   MOZ_ASSERT(gfx); // already checked the draw target above
 
   if (aGraphicOpacity != 1.0f) {
     gfx->Save();
@@ -394,48 +393,47 @@ nsSVGPatternFrame::PaintPattern(const Dr
 
   if (aSource->IsFrameOfType(nsIFrame::eSVGGeometry)) {
     // Set the geometrical parent of the pattern we are rendering
     patternWithChildren->mSource = static_cast<SVGGeometryFrame*>(aSource);
   }
 
   // Delay checking NS_FRAME_DRAWING_AS_PAINTSERVER bit until here so we can
   // give back a clear surface if there's a loop
-  DrawResult result = DrawResult::SUCCESS;
   if (!(patternWithChildren->GetStateBits() & NS_FRAME_DRAWING_AS_PAINTSERVER)) {
     patternWithChildren->AddStateBits(NS_FRAME_DRAWING_AS_PAINTSERVER);
     for (nsIFrame* kid = firstKid; kid;
          kid = kid->GetNextSibling()) {
       // The CTM of each frame referencing us can be different
       nsISVGChildFrame* SVGFrame = do_QueryFrame(kid);
       if (SVGFrame) {
         SVGFrame->NotifySVGChanged(nsISVGChildFrame::TRANSFORM_CHANGED);
       }
       gfxMatrix tm = *(patternWithChildren->mCTM);
       if (kid->GetContent()->IsSVGElement()) {
         tm = static_cast<nsSVGElement*>(kid->GetContent())->
                PrependLocalTransformsTo(tm, eUserSpaceToParent);
       }
-
-      result &= nsSVGUtils::PaintFrameWithEffects(kid, *gfx, tm);
+      DrawResult result = nsSVGUtils::PaintFrameWithEffects(kid, *gfx, tm);
+      if (result != DrawResult::SUCCESS) {
+        return nullptr;
+      }
     }
-
     patternWithChildren->RemoveStateBits(NS_FRAME_DRAWING_AS_PAINTSERVER);
   }
 
   patternWithChildren->mSource = nullptr;
 
   if (aGraphicOpacity != 1.0f) {
     gfx->PopGroupAndBlend();
     gfx->Restore();
   }
 
   // caller now owns the surface
-  RefPtr<SourceSurface> surf = dt->Snapshot();
-  return MakePair(result, Move(surf));
+  return dt->Snapshot();
 }
 
 /* Will probably need something like this... */
 // How do we handle the insertion of a new frame?
 // We really don't want to rerender this every time,
 // do we?
 nsSVGPatternFrame*
 nsSVGPatternFrame::GetPatternWithChildren()
@@ -704,49 +702,47 @@ nsSVGPatternFrame::ConstructCTM(const ns
     viewBoxRect.width, viewBoxRect.height,
     GetPreserveAspectRatio());
 
   return ThebesMatrix(tm);
 }
 
 //----------------------------------------------------------------------
 // nsSVGPaintServerFrame methods:
-mozilla::Pair<DrawResult, RefPtr<gfxPattern>>
+
+already_AddRefed<gfxPattern>
 nsSVGPatternFrame::GetPaintServerPattern(nsIFrame *aSource,
                                          const DrawTarget* aDrawTarget,
                                          const gfxMatrix& aContextMatrix,
                                          nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
                                          float aGraphicOpacity,
                                          const gfxRect *aOverrideBounds)
 {
   if (aGraphicOpacity == 0.0f) {
     RefPtr<gfxPattern> pattern = new gfxPattern(Color());
-    return MakePair(DrawResult::SUCCESS, Move(pattern));
+    return pattern.forget();
   }
 
   // Paint it!
   Matrix pMatrix;
-  RefPtr<SourceSurface> surface;
-  DrawResult result = DrawResult::SUCCESS;
-  Tie(result, surface) =
+  RefPtr<SourceSurface> surface =
     PaintPattern(aDrawTarget, &pMatrix, ToMatrix(aContextMatrix), aSource,
                  aFillOrStroke, aGraphicOpacity, aOverrideBounds);
 
   if (!surface) {
-    return MakePair(result, RefPtr<gfxPattern>());
+    return nullptr;
   }
 
   RefPtr<gfxPattern> pattern = new gfxPattern(surface, pMatrix);
 
-  if (!pattern || pattern->CairoStatus()) {
-    return MakePair(DrawResult::TEMPORARY_ERROR, RefPtr<gfxPattern>());
-  }
+  if (!pattern || pattern->CairoStatus())
+    return nullptr;
 
   pattern->SetExtend(ExtendMode::REPEAT);
-  return MakePair(result, Move(pattern));
+  return pattern.forget();
 }
 
 // -------------------------------------------------------------------------
 // Public functions
 // -------------------------------------------------------------------------
 
 nsIFrame* NS_NewSVGPatternFrame(nsIPresShell*   aPresShell,
                                 nsStyleContext* aContext)
--- a/layout/svg/nsSVGPatternFrame.h
+++ b/layout/svg/nsSVGPatternFrame.h
@@ -35,17 +35,17 @@ public:
   NS_DECL_FRAMEARENA_HELPERS
 
   friend nsIFrame* NS_NewSVGPatternFrame(nsIPresShell* aPresShell,
                                          nsStyleContext* aContext);
 
   explicit nsSVGPatternFrame(nsStyleContext* aContext);
 
   // nsSVGPaintServerFrame methods:
-  virtual mozilla::Pair<DrawResult, RefPtr<gfxPattern>>
+  virtual already_AddRefed<gfxPattern>
     GetPaintServerPattern(nsIFrame *aSource,
                           const DrawTarget* aDrawTarget,
                           const gfxMatrix& aContextMatrix,
                           nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
                           float aOpacity,
                           const gfxRect *aOverrideBounds) override;
 
 public:
@@ -103,17 +103,17 @@ protected:
     return GetPreserveAspectRatio(mContent);
   }
   const nsSVGLength2 *GetLengthValue(uint32_t aIndex, nsIContent *aDefault);
   const nsSVGLength2 *GetLengthValue(uint32_t aIndex)
   {
     return GetLengthValue(aIndex, mContent);
   }
 
-  mozilla::Pair<DrawResult, RefPtr<SourceSurface>>
+  already_AddRefed<SourceSurface>
   PaintPattern(const DrawTarget* aDrawTarget,
                Matrix *patternMatrix,
                const Matrix &aContextMatrix,
                nsIFrame *aSource,
                nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
                float aGraphicOpacity,
                const gfxRect *aOverrideBounds);
 
--- a/layout/svg/nsSVGUtils.cpp
+++ b/layout/svg/nsSVGUtils.cpp
@@ -1445,25 +1445,25 @@ nsSVGUtils::GetFallbackOrPaintColor(nsSt
       nscolor colors[2] = { color, paintIfVisited.GetColor() };
       return nsStyleContext::CombineVisitedColors(
                colors, aStyleContext->RelevantLinkVisited());
     }
   }
   return color;
 }
 
-/* static */ DrawResult
+/* static */ void
 nsSVGUtils::MakeFillPatternFor(nsIFrame* aFrame,
                                gfxContext* aContext,
                                GeneralPattern* aOutPattern,
                                SVGContextPaint* aContextPaint)
 {
   const nsStyleSVG* style = aFrame->StyleSVG();
   if (style->mFill.Type() == eStyleSVGPaintType_None) {
-    return DrawResult::SUCCESS;
+    return;
   }
 
   const float opacity = aFrame->StyleEffects()->mOpacity;
 
   float fillOpacity = GetOpacity(style->FillOpacitySource(),
                                  style->mFillOpacity,
                                  aContextPaint);
   if (opacity < 1.0f &&
@@ -1473,71 +1473,65 @@ nsSVGUtils::MakeFillPatternFor(nsIFrame*
     fillOpacity *= opacity;
   }
 
   const DrawTarget* dt = aContext->GetDrawTarget();
 
   nsSVGPaintServerFrame *ps =
     nsSVGEffects::GetPaintServer(aFrame, &nsStyleSVG::mFill,
                                  nsSVGEffects::FillProperty());
-  DrawResult result = DrawResult::SUCCESS;
   if (ps) {
-    RefPtr<gfxPattern> pattern;
-    Tie(result, pattern) =
+    RefPtr<gfxPattern> pattern =
       ps->GetPaintServerPattern(aFrame, dt, aContext->CurrentMatrix(),
                                 &nsStyleSVG::mFill, fillOpacity);
     if (pattern) {
       pattern->CacheColorStops(dt);
       aOutPattern->Init(*pattern->GetPattern(dt));
-      return result;
+      return;
     }
   }
 
   if (aContextPaint) {
     RefPtr<gfxPattern> pattern;
     switch (style->mFill.Type()) {
     case eStyleSVGPaintType_ContextFill:
-      Tie(result, pattern) =
-        aContextPaint->GetFillPattern(dt, fillOpacity,
-                                      aContext->CurrentMatrix());
+      pattern = aContextPaint->GetFillPattern(dt, fillOpacity,
+                                              aContext->CurrentMatrix());
       break;
     case eStyleSVGPaintType_ContextStroke:
-      Tie(result, pattern) =
-        aContextPaint->GetStrokePattern(dt, fillOpacity,
-                                        aContext->CurrentMatrix());
+      pattern = aContextPaint->GetStrokePattern(dt, fillOpacity,
+                                                aContext->CurrentMatrix());
       break;
     default:
       ;
     }
     if (pattern) {
       aOutPattern->Init(*pattern->GetPattern(dt));
-      return result;
+      return;
     }
   }
 
   // On failure, use the fallback colour in case we have an
   // objectBoundingBox where the width or height of the object is zero.
   // See http://www.w3.org/TR/SVG11/coords.html#ObjectBoundingBox
   Color color(Color::FromABGR(GetFallbackOrPaintColor(aFrame->StyleContext(),
                                                       &nsStyleSVG::mFill)));
   color.a *= fillOpacity;
   aOutPattern->InitColorPattern(ToDeviceColor(color));
-
-  return result;
 }
 
-/* static */ DrawResult
+/* static */ void
 nsSVGUtils::MakeStrokePatternFor(nsIFrame* aFrame,
                                  gfxContext* aContext,
                                  GeneralPattern* aOutPattern,
                                  SVGContextPaint* aContextPaint)
 {
   const nsStyleSVG* style = aFrame->StyleSVG();
   if (style->mStroke.Type() == eStyleSVGPaintType_None) {
-    return DrawResult::SUCCESS;
+    return;
   }
 
   const float opacity = aFrame->StyleEffects()->mOpacity;
 
   float strokeOpacity = GetOpacity(style->StrokeOpacitySource(),
                                    style->mStrokeOpacity,
                                    aContextPaint);
   if (opacity < 1.0f &&
@@ -1547,60 +1541,54 @@ nsSVGUtils::MakeStrokePatternFor(nsIFram
     strokeOpacity *= opacity;
   }
 
   const DrawTarget* dt = aContext->GetDrawTarget();
 
   nsSVGPaintServerFrame *ps =
     nsSVGEffects::GetPaintServer(aFrame, &nsStyleSVG::mStroke,
                                  nsSVGEffects::StrokeProperty());
-  DrawResult result = DrawResult::SUCCESS;
   if (ps) {
-    RefPtr<gfxPattern> pattern;
-    Tie(result, pattern) =
+    RefPtr<gfxPattern> pattern =
       ps->GetPaintServerPattern(aFrame, dt, aContext->CurrentMatrix(),
                                 &nsStyleSVG::mStroke, strokeOpacity);
     if (pattern) {
       pattern->CacheColorStops(dt);
       aOutPattern->Init(*pattern->GetPattern(dt));
-      return result;
+      return;
     }
   }
 
   if (aContextPaint) {
     RefPtr<gfxPattern> pattern;
     switch (style->mStroke.Type()) {
     case eStyleSVGPaintType_ContextFill:
-      Tie(result, pattern) =
-        aContextPaint->GetFillPattern(dt, strokeOpacity,
-                                      aContext->CurrentMatrix());
+      pattern = aContextPaint->GetFillPattern(dt, strokeOpacity,
+                                              aContext->CurrentMatrix());
       break;
     case eStyleSVGPaintType_ContextStroke:
-      Tie(result, pattern) =
-        aContextPaint->GetStrokePattern(dt, strokeOpacity,
-                                        aContext->CurrentMatrix());
+      pattern = aContextPaint->GetStrokePattern(dt, strokeOpacity,
+                                                aContext->CurrentMatrix());
       break;
     default:
       ;
     }
     if (pattern) {
       aOutPattern->Init(*pattern->GetPattern(dt));
-      return result;
+      return;
     }
   }
 
   // On failure, use the fallback colour in case we have an
   // objectBoundingBox where the width or height of the object is zero.
   // See http://www.w3.org/TR/SVG11/coords.html#ObjectBoundingBox
   Color color(Color::FromABGR(GetFallbackOrPaintColor(aFrame->StyleContext(),
                                                       &nsStyleSVG::mStroke)));
   color.a *= strokeOpacity;
   aOutPattern->InitColorPattern(ToDeviceColor(color));
-
-  return DrawResult::SUCCESS;
 }
 
 /* static */ float
 nsSVGUtils::GetOpacity(nsStyleSVGOpacitySource aOpacityType,
                        const float& aOpacity,
                        SVGContextPaint *aContextPaint)
 {
   float opacity = 1.0f;
--- a/layout/svg/nsSVGUtils.h
+++ b/layout/svg/nsSVGUtils.h
@@ -498,23 +498,23 @@ public:
   {
     return NS_lround(std::max(double(INT32_MIN),
                             std::min(double(INT32_MAX), aVal)));
   }
 
   static nscolor GetFallbackOrPaintColor(nsStyleContext *aStyleContext,
                                          nsStyleSVGPaint nsStyleSVG::*aFillOrStroke);
 
-  static DrawResult
+  static void
   MakeFillPatternFor(nsIFrame *aFrame,
                      gfxContext* aContext,
                      GeneralPattern* aOutPattern,
                      SVGContextPaint* aContextPaint = nullptr);
 
-  static DrawResult
+  static void
   MakeStrokePatternFor(nsIFrame* aFrame,
                        gfxContext* aContext,
                        GeneralPattern* aOutPattern,
                        SVGContextPaint* aContextPaint = nullptr);
 
   static float GetOpacity(nsStyleSVGOpacitySource aOpacityType,
                           const float& aOpacity,
                           SVGContextPaint* aContextPaint);