Backed out changeset 3710f0b135b8 for wrong commit message
authorDavid Zbarsky <dzbarsky@gmail.com>
Thu, 07 Mar 2013 02:16:30 -0500
changeset 124052 9b7c6a46f1f60f50c5758f2bb69e048d22a251f1
parent 124051 3710f0b135b8b1a018050f2580eefc24b79439a8
child 124053 35f383c97e07ad0fdf8c685a15388a69d7fddca9
push id24406
push userryanvm@gmail.com
push dateThu, 07 Mar 2013 17:19:02 +0000
treeherdermozilla-central@71395a927025 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone22.0a1
backs out3710f0b135b8b1a018050f2580eefc24b79439a8
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 3710f0b135b8 for wrong commit message
content/svg/content/src/Makefile.in
content/svg/content/src/SVGFEBlendElement.cpp
content/svg/content/src/SVGFEBlendElement.h
content/svg/content/src/nsSVGFilters.cpp
content/svg/content/src/nsSVGFilters.h
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfoClasses.h
dom/interfaces/svg/nsIDOMSVGFilters.idl
dom/webidl/SVGFEBlendElement.webidl
dom/webidl/SVGFilterPrimitiveStandardAttributes.webidl
dom/webidl/WebIDL.mk
layout/svg/nsSVGFilterInstance.cpp
--- a/content/svg/content/src/Makefile.in
+++ b/content/svg/content/src/Makefile.in
@@ -74,17 +74,16 @@ CPPSRCS		= \
 		SVGAttrValueWrapper.cpp \
 		SVGClipPathElement.cpp \
 		SVGCircleElement.cpp \
 		SVGContentUtils.cpp \
 		SVGDefsElement.cpp \
 		SVGDescElement.cpp \
 		SVGElementFactory.cpp \
 		SVGEllipseElement.cpp \
-		SVGFEBlendElement.cpp \
 		SVGFilterElement.cpp \
 		SVGForeignObjectElement.cpp \
 		SVGFragmentIdentifier.cpp \
 		SVGGElement.cpp \
 		SVGGradientElement.cpp \
 		SVGGraphicsElement.cpp \
 		SVGImageElement.cpp \
 		SVGIntegerPairSMILType.cpp \
@@ -166,17 +165,16 @@ EXPORTS_mozilla/dom = \
 	SVGAnimateMotionElement.h \
 	SVGAnimationElement.h \
 	SVGClipPathElement.h \
 	SVGCircleElement.h \
 	SVGComponentTransferFunctionElement.h \
 	SVGDefsElement.h \
 	SVGDescElement.h \
 	SVGEllipseElement.h \
-	SVGFEBlendElement.h \
 	SVGFilterElement.h \
 	SVGForeignObjectElement.h \
 	SVGGElement.h \
 	SVGGradientElement.h \
 	SVGGraphicsElement.h \
 	SVGImageElement.h \
 	SVGLineElement.h \
 	SVGMarkerElement.h \
deleted file mode 100644
--- a/content/svg/content/src/SVGFEBlendElement.cpp
+++ /dev/null
@@ -1,169 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "mozilla/dom/SVGFEBlendElement.h"
-#include "mozilla/dom/SVGFEBlendElementBinding.h"
-#include "nsSVGUtils.h"
-
-NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(FEBlend)
-
-namespace mozilla {
-namespace dom {
-
-JSObject*
-SVGFEBlendElement::WrapNode(JSContext *aCx, JSObject *aScope, bool *aTriedToWrap)
-{
-  return SVGFEBlendElementBinding::Wrap(aCx, aScope, this, aTriedToWrap);
-}
-
-nsSVGEnumMapping SVGFEBlendElement::sModeMap[] = {
-  {&nsGkAtoms::normal, SVG_FEBLEND_MODE_NORMAL},
-  {&nsGkAtoms::multiply, SVG_FEBLEND_MODE_MULTIPLY},
-  {&nsGkAtoms::screen, SVG_FEBLEND_MODE_SCREEN},
-  {&nsGkAtoms::darken, SVG_FEBLEND_MODE_DARKEN},
-  {&nsGkAtoms::lighten, SVG_FEBLEND_MODE_LIGHTEN},
-  {nullptr, 0}
-};
-
-nsSVGElement::EnumInfo SVGFEBlendElement::sEnumInfo[1] =
-{
-  { &nsGkAtoms::mode,
-    sModeMap,
-    SVG_FEBLEND_MODE_NORMAL
-  }
-};
-
-nsSVGElement::StringInfo SVGFEBlendElement::sStringInfo[3] =
-{
-  { &nsGkAtoms::result, kNameSpaceID_None, true },
-  { &nsGkAtoms::in, kNameSpaceID_None, true },
-  { &nsGkAtoms::in2, kNameSpaceID_None, true }
-};
-
-//----------------------------------------------------------------------
-// nsISupports methods
-
-NS_IMPL_ISUPPORTS_INHERITED3(SVGFEBlendElement, SVGFEBlendElementBase,
-                             nsIDOMNode, nsIDOMElement,
-                             nsIDOMSVGElement)
-//----------------------------------------------------------------------
-// nsIDOMNode methods
-
-NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGFEBlendElement)
-
-//----------------------------------------------------------------------
-// nsIDOMSVGFEBlendElement methods
-
-already_AddRefed<nsIDOMSVGAnimatedString>
-SVGFEBlendElement::In1()
-{
-  return mStringAttributes[IN1].ToDOMAnimatedString(this);
-}
-
-already_AddRefed<nsIDOMSVGAnimatedString>
-SVGFEBlendElement::In2()
-{
-  return mStringAttributes[IN2].ToDOMAnimatedString(this);
-}
-
-already_AddRefed<nsIDOMSVGAnimatedEnumeration>
-SVGFEBlendElement::Mode()
-{
-  return mEnumAttributes[MODE].ToDOMAnimatedEnum(this);
-}
-
-nsresult
-SVGFEBlendElement::Filter(nsSVGFilterInstance* aInstance,
-                          const nsTArray<const Image*>& aSources,
-                          const Image* aTarget,
-                          const nsIntRect& rect)
-{
-  CopyRect(aTarget, aSources[0], rect);
-
-  uint8_t* sourceData = aSources[1]->mImage->Data();
-  uint8_t* targetData = aTarget->mImage->Data();
-  uint32_t stride = aTarget->mImage->Stride();
-
-  uint16_t mode = mEnumAttributes[MODE].GetAnimValue();
-
-  for (int32_t x = rect.x; x < rect.XMost(); x++) {
-    for (int32_t y = rect.y; y < rect.YMost(); y++) {
-      uint32_t targIndex = y * stride + 4 * x;
-      uint32_t qa = targetData[targIndex + GFX_ARGB32_OFFSET_A];
-      uint32_t qb = sourceData[targIndex + GFX_ARGB32_OFFSET_A];
-      for (int32_t i = std::min(GFX_ARGB32_OFFSET_B, GFX_ARGB32_OFFSET_R);
-           i <= std::max(GFX_ARGB32_OFFSET_B, GFX_ARGB32_OFFSET_R); i++) {
-        uint32_t ca = targetData[targIndex + i];
-        uint32_t cb = sourceData[targIndex + i];
-        uint32_t val;
-        switch (mode) {
-          case SVG_FEBLEND_MODE_NORMAL:
-            val = (255 - qa) * cb + 255 * ca;
-            break;
-          case SVG_FEBLEND_MODE_MULTIPLY:
-            val = ((255 - qa) * cb + (255 - qb + cb) * ca);
-            break;
-          case SVG_FEBLEND_MODE_SCREEN:
-            val = 255 * (cb + ca) - ca * cb;
-            break;
-          case SVG_FEBLEND_MODE_DARKEN:
-            val = std::min((255 - qa) * cb + 255 * ca,
-                         (255 - qb) * ca + 255 * cb);
-            break;
-          case SVG_FEBLEND_MODE_LIGHTEN:
-            val = std::max((255 - qa) * cb + 255 * ca,
-                         (255 - qb) * ca + 255 * cb);
-            break;
-          default:
-            return NS_ERROR_FAILURE;
-            break;
-        }
-        val = std::min(val / 255, 255U);
-        targetData[targIndex + i] =  static_cast<uint8_t>(val);
-      }
-      uint32_t alpha = 255 * 255 - (255 - qa) * (255 - qb);
-      FAST_DIVIDE_BY_255(targetData[targIndex + GFX_ARGB32_OFFSET_A], alpha);
-    }
-  }
-  return NS_OK;
-}
-
-bool
-SVGFEBlendElement::AttributeAffectsRendering(int32_t aNameSpaceID,
-                                             nsIAtom* aAttribute) const
-{
-  return SVGFEBlendElementBase::AttributeAffectsRendering(aNameSpaceID, aAttribute) ||
-         (aNameSpaceID == kNameSpaceID_None &&
-          (aAttribute == nsGkAtoms::in ||
-           aAttribute == nsGkAtoms::in2 ||
-           aAttribute == nsGkAtoms::mode));
-}
-
-void
-SVGFEBlendElement::GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources)
-{
-  aSources.AppendElement(nsSVGStringInfo(&mStringAttributes[IN1], this));
-  aSources.AppendElement(nsSVGStringInfo(&mStringAttributes[IN2], this));
-}
-
-//----------------------------------------------------------------------
-// nsSVGElement methods
-
-nsSVGElement::EnumAttributesInfo
-SVGFEBlendElement::GetEnumInfo()
-{
-  return EnumAttributesInfo(mEnumAttributes, sEnumInfo,
-                            ArrayLength(sEnumInfo));
-}
-
-nsSVGElement::StringAttributesInfo
-SVGFEBlendElement::GetStringInfo()
-{
-  return StringAttributesInfo(mStringAttributes, sStringInfo,
-                              ArrayLength(sStringInfo));
-}
-
-} // namespace dom
-} // namespace mozilla
deleted file mode 100644
--- a/content/svg/content/src/SVGFEBlendElement.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla_dom_SVGFEBlendElement_h
-#define mozilla_dom_SVGFEBlendElement_h
-
-#include "nsSVGFilters.h"
-#include "nsSVGEnum.h"
-
-nsresult NS_NewSVGFEBlendElement(nsIContent **aResult,
-                                 already_AddRefed<nsINodeInfo> aNodeInfo);
-namespace mozilla {
-namespace dom {
-
-static const unsigned short SVG_FEBLEND_MODE_UNKNOWN = 0;
-static const unsigned short SVG_FEBLEND_MODE_NORMAL = 1;
-static const unsigned short SVG_FEBLEND_MODE_MULTIPLY = 2;
-static const unsigned short SVG_FEBLEND_MODE_SCREEN = 3;
-static const unsigned short SVG_FEBLEND_MODE_DARKEN = 4;
-static const unsigned short SVG_FEBLEND_MODE_LIGHTEN = 5;
-
-typedef nsSVGFE SVGFEBlendElementBase;
-
-class SVGFEBlendElement : public SVGFEBlendElementBase,
-                          public nsIDOMSVGElement
-{
-  friend nsresult (::NS_NewSVGFEBlendElement(nsIContent **aResult,
-                                             already_AddRefed<nsINodeInfo> aNodeInfo));
-protected:
-  SVGFEBlendElement(already_AddRefed<nsINodeInfo> aNodeInfo)
-    : SVGFEBlendElementBase(aNodeInfo)
-  {
-    SetIsDOMBinding();
-  }
-  virtual JSObject* WrapNode(JSContext *cx, JSObject *scope, bool *triedToWrap) MOZ_OVERRIDE;
-
-public:
-  // interfaces:
-  NS_DECL_ISUPPORTS_INHERITED
-
-  virtual nsresult Filter(nsSVGFilterInstance* aInstance,
-                          const nsTArray<const Image*>& aSources,
-                          const Image* aTarget,
-                          const nsIntRect& aDataRect);
-  virtual bool AttributeAffectsRendering(
-          int32_t aNameSpaceID, nsIAtom* aAttribute) const;
-  virtual nsSVGString& GetResultImageName() { return mStringAttributes[RESULT]; }
-  virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources);
-
-  NS_FORWARD_NSIDOMSVGELEMENT(SVGFEBlendElementBase::)
-
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
-
-  virtual nsIDOMNode* AsDOMNode() { return this; }
-
-  // WebIDL
-  already_AddRefed<nsIDOMSVGAnimatedString> In1();
-  already_AddRefed<nsIDOMSVGAnimatedString> In2();
-  already_AddRefed<nsIDOMSVGAnimatedEnumeration> Mode();
-
-protected:
-
-  virtual EnumAttributesInfo GetEnumInfo();
-  virtual StringAttributesInfo GetStringInfo();
-
-  enum { MODE };
-  nsSVGEnum mEnumAttributes[1];
-  static nsSVGEnumMapping sModeMap[];
-  static EnumInfo sEnumInfo[1];
-
-  enum { RESULT, IN1, IN2 };
-  nsSVGString mStringAttributes[3];
-  static StringInfo sStringInfo[3];
-};
-
-} // namespace dom
-} // namespace mozilla
-
-#endif // mozilla_dom_SVGFEBlendElement_h
--- a/content/svg/content/src/nsSVGFilters.cpp
+++ b/content/svg/content/src/nsSVGFilters.cpp
@@ -32,45 +32,56 @@
 #include "nsIInterfaceRequestorUtils.h"
 #include "mozilla/dom/SVGFilterElement.h"
 #include "nsSVGString.h"
 #include "nsSVGEffects.h"
 #include "gfxUtils.h"
 #include "SVGContentUtils.h"
 #include <algorithm>
 #include "nsContentUtils.h"
-#include "mozilla/dom/SVGAnimatedLength.h"
 #include "mozilla/dom/SVGComponentTransferFunctionElement.h"
 #include "mozilla/dom/SVGFEFuncAElementBinding.h"
 #include "mozilla/dom/SVGFEFuncBElementBinding.h"
 #include "mozilla/dom/SVGFEFuncGElementBinding.h"
 #include "mozilla/dom/SVGFEFuncRElementBinding.h"
 
 #if defined(XP_WIN) 
 // Prevent Windows redefining LoadImage
 #undef LoadImage
 #endif
 
 #define NUM_ENTRIES_IN_4x5_MATRIX 20
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
-void
+static void
 CopyDataRect(uint8_t *aDest, const uint8_t *aSrc, uint32_t aStride,
              const nsIntRect& aDataRect)
 {
   for (int32_t y = aDataRect.y; y < aDataRect.YMost(); y++) {
     memcpy(aDest + y * aStride + 4 * aDataRect.x,
            aSrc + y * aStride + 4 * aDataRect.x,
            4 * aDataRect.width);
   }
 }
 
 static void
+CopyRect(const nsSVGFE::Image* aDest, const nsSVGFE::Image* aSrc, const nsIntRect& aDataRect)
+{
+  NS_ASSERTION(aDest->mImage->Stride() == aSrc->mImage->Stride(), "stride mismatch");
+  NS_ASSERTION(aDest->mImage->GetSize() == aSrc->mImage->GetSize(), "size mismatch");
+  NS_ASSERTION(nsIntRect(0, 0, aDest->mImage->Width(), aDest->mImage->Height()).Contains(aDataRect),
+               "aDataRect out of bounds");
+
+  CopyDataRect(aDest->mImage->Data(), aSrc->mImage->Data(),
+               aSrc->mImage->Stride(), aDataRect);
+}
+
+static void
 CopyAndScaleDeviceOffset(const gfxImageSurface *aImage, gfxImageSurface *aResult,
                          gfxFloat kernelX, gfxFloat kernelY)
 {
   gfxPoint deviceOffset = aImage->GetDeviceOffset();
   deviceOffset.x /= kernelX;
   deviceOffset.y /= kernelY;
   aResult->SetDeviceOffset(deviceOffset);
 }
@@ -246,76 +257,41 @@ nsSVGFE::AttributeAffectsRendering(int32
 }
 
 //----------------------------------------------------------------------
 // nsIDOMSVGFilterPrimitiveStandardAttributes methods
 
 /* readonly attribute nsIDOMSVGAnimatedLength x; */
 NS_IMETHODIMP nsSVGFE::GetX(nsIDOMSVGAnimatedLength * *aX)
 {
-  *aX = X().get();
-  return NS_OK;
-}
-
-already_AddRefed<SVGAnimatedLength>
-nsSVGFE::X()
-{
-  return mLengthAttributes[ATTR_X].ToDOMAnimatedLength(this);
+  return mLengthAttributes[X].ToDOMAnimatedLength(aX, this);
 }
 
 /* readonly attribute nsIDOMSVGAnimatedLength y; */
 NS_IMETHODIMP nsSVGFE::GetY(nsIDOMSVGAnimatedLength * *aY)
 {
-  *aY = Y().get();
-  return NS_OK;
-}
-
-already_AddRefed<SVGAnimatedLength>
-nsSVGFE::Y()
-{
-  return mLengthAttributes[ATTR_Y].ToDOMAnimatedLength(this);
+  return mLengthAttributes[Y].ToDOMAnimatedLength(aY, this);
 }
 
 /* readonly attribute nsIDOMSVGAnimatedLength width; */
 NS_IMETHODIMP nsSVGFE::GetWidth(nsIDOMSVGAnimatedLength * *aWidth)
 {
-  *aWidth = Width().get();
-  return NS_OK;
-}
-
-already_AddRefed<SVGAnimatedLength>
-nsSVGFE::Width()
-{
-  return mLengthAttributes[ATTR_WIDTH].ToDOMAnimatedLength(this);
+  return mLengthAttributes[WIDTH].ToDOMAnimatedLength(aWidth, this);
 }
 
 /* readonly attribute nsIDOMSVGAnimatedLength height; */
 NS_IMETHODIMP nsSVGFE::GetHeight(nsIDOMSVGAnimatedLength * *aHeight)
 {
-  *aHeight = Height().get();
-  return NS_OK;
-}
-
-already_AddRefed<SVGAnimatedLength>
-nsSVGFE::Height()
-{
-  return mLengthAttributes[ATTR_HEIGHT].ToDOMAnimatedLength(this);
+  return mLengthAttributes[HEIGHT].ToDOMAnimatedLength(aHeight, this);
 }
 
 /* readonly attribute nsIDOMSVGAnimatedString result; */
 NS_IMETHODIMP nsSVGFE::GetResult(nsIDOMSVGAnimatedString * *aResult)
 {
-  *aResult = Result().get();
-  return NS_OK;
-}
-
-already_AddRefed<nsIDOMSVGAnimatedString>
-nsSVGFE::Result()
-{
-  return GetResultImageName().ToDOMAnimatedString(this);
+  return GetResultImageName().ToDOMAnimatedString(aResult, this);
 }
 
 //----------------------------------------------------------------------
 // nsIContent methods
 
 NS_IMETHODIMP_(bool)
 nsSVGFE::IsAttributeMapped(const nsIAtom* name) const
 {
@@ -328,20 +304,20 @@ nsSVGFE::IsAttributeMapped(const nsIAtom
 }
 
 //----------------------------------------------------------------------
 // nsSVGElement methods
 
 /* virtual */ bool
 nsSVGFE::HasValidDimensions() const
 {
-  return (!mLengthAttributes[ATTR_WIDTH].IsExplicitlySet() ||
-           mLengthAttributes[ATTR_WIDTH].GetAnimValInSpecifiedUnits() > 0) &&
-         (!mLengthAttributes[ATTR_HEIGHT].IsExplicitlySet() ||
-           mLengthAttributes[ATTR_HEIGHT].GetAnimValInSpecifiedUnits() > 0);
+  return (!mLengthAttributes[WIDTH].IsExplicitlySet() ||
+           mLengthAttributes[WIDTH].GetAnimValInSpecifiedUnits() > 0) &&
+         (!mLengthAttributes[HEIGHT].IsExplicitlySet() || 
+           mLengthAttributes[HEIGHT].GetAnimValInSpecifiedUnits() > 0);
 }
 
 nsSVGElement::LengthAttributesInfo
 nsSVGFE::GetLengthInfo()
 {
   return LengthAttributesInfo(mLengthAttributes, sLengthInfo,
                               ArrayLength(sLengthInfo));
 }
@@ -825,16 +801,233 @@ nsSVGFEGaussianBlurElement::GetNumberPai
 
 nsSVGElement::StringAttributesInfo
 nsSVGFEGaussianBlurElement::GetStringInfo()
 {
   return StringAttributesInfo(mStringAttributes, sStringInfo,
                               ArrayLength(sStringInfo));
 }
 
+//---------------------Blend------------------------
+
+typedef nsSVGFE nsSVGFEBlendElementBase;
+
+class nsSVGFEBlendElement : public nsSVGFEBlendElementBase,
+                            public nsIDOMSVGFEBlendElement
+{
+  friend nsresult NS_NewSVGFEBlendElement(nsIContent **aResult,
+                                          already_AddRefed<nsINodeInfo> aNodeInfo);
+protected:
+  nsSVGFEBlendElement(already_AddRefed<nsINodeInfo> aNodeInfo)
+    : nsSVGFEBlendElementBase(aNodeInfo) {}
+
+public:
+  // interfaces:
+  NS_DECL_ISUPPORTS_INHERITED
+
+  // FE Base
+  NS_FORWARD_NSIDOMSVGFILTERPRIMITIVESTANDARDATTRIBUTES(nsSVGFEBlendElementBase::)
+
+  virtual nsresult Filter(nsSVGFilterInstance* aInstance,
+                          const nsTArray<const Image*>& aSources,
+                          const Image* aTarget,
+                          const nsIntRect& aDataRect);
+  virtual bool AttributeAffectsRendering(
+          int32_t aNameSpaceID, nsIAtom* aAttribute) const;
+  virtual nsSVGString& GetResultImageName() { return mStringAttributes[RESULT]; }
+  virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources);
+
+  // Blend
+  NS_DECL_NSIDOMSVGFEBLENDELEMENT
+
+  NS_FORWARD_NSIDOMSVGELEMENT(nsSVGFEBlendElementBase::)
+
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
+  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
+
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+
+  virtual nsXPCClassInfo* GetClassInfo();
+
+  virtual nsIDOMNode* AsDOMNode() { return this; }
+protected:
+
+  virtual EnumAttributesInfo GetEnumInfo();
+  virtual StringAttributesInfo GetStringInfo();
+
+  enum { MODE };
+  nsSVGEnum mEnumAttributes[1];
+  static nsSVGEnumMapping sModeMap[];
+  static EnumInfo sEnumInfo[1];
+
+  enum { RESULT, IN1, IN2 };
+  nsSVGString mStringAttributes[3];
+  static StringInfo sStringInfo[3];
+};
+
+nsSVGEnumMapping nsSVGFEBlendElement::sModeMap[] = {
+  {&nsGkAtoms::normal, nsSVGFEBlendElement::SVG_MODE_NORMAL},
+  {&nsGkAtoms::multiply, nsSVGFEBlendElement::SVG_MODE_MULTIPLY},
+  {&nsGkAtoms::screen, nsSVGFEBlendElement::SVG_MODE_SCREEN},
+  {&nsGkAtoms::darken, nsSVGFEBlendElement::SVG_MODE_DARKEN},
+  {&nsGkAtoms::lighten, nsSVGFEBlendElement::SVG_MODE_LIGHTEN},
+  {nullptr, 0}
+};
+
+nsSVGElement::EnumInfo nsSVGFEBlendElement::sEnumInfo[1] =
+{
+  { &nsGkAtoms::mode,
+    sModeMap,
+    nsSVGFEBlendElement::SVG_MODE_NORMAL
+  }
+};
+
+nsSVGElement::StringInfo nsSVGFEBlendElement::sStringInfo[3] =
+{
+  { &nsGkAtoms::result, kNameSpaceID_None, true },
+  { &nsGkAtoms::in, kNameSpaceID_None, true },
+  { &nsGkAtoms::in2, kNameSpaceID_None, true }
+};
+
+NS_IMPL_NS_NEW_SVG_ELEMENT(FEBlend)
+
+//----------------------------------------------------------------------
+// nsISupports methods
+
+NS_IMPL_ADDREF_INHERITED(nsSVGFEBlendElement,nsSVGFEBlendElementBase)
+NS_IMPL_RELEASE_INHERITED(nsSVGFEBlendElement,nsSVGFEBlendElementBase)
+
+DOMCI_NODE_DATA(SVGFEBlendElement, nsSVGFEBlendElement)
+
+NS_INTERFACE_TABLE_HEAD(nsSVGFEBlendElement)
+  NS_NODE_INTERFACE_TABLE5(nsSVGFEBlendElement, nsIDOMNode, nsIDOMElement,
+                           nsIDOMSVGElement,
+                           nsIDOMSVGFilterPrimitiveStandardAttributes,
+                           nsIDOMSVGFEBlendElement)
+  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGFEBlendElement)
+NS_INTERFACE_MAP_END_INHERITING(nsSVGFEBlendElementBase)
+
+//----------------------------------------------------------------------
+// nsIDOMNode methods
+
+
+NS_IMPL_ELEMENT_CLONE_WITH_INIT(nsSVGFEBlendElement)
+
+//----------------------------------------------------------------------
+// nsIDOMSVGFEBlendElement methods
+
+/* readonly attribute nsIDOMSVGAnimatedString in1; */
+NS_IMETHODIMP nsSVGFEBlendElement::GetIn1(nsIDOMSVGAnimatedString * *aIn)
+{
+  return mStringAttributes[IN1].ToDOMAnimatedString(aIn, this);
+}
+
+/* readonly attribute nsIDOMSVGAnimatedString in2; */
+NS_IMETHODIMP nsSVGFEBlendElement::GetIn2(nsIDOMSVGAnimatedString * *aIn)
+{
+  return mStringAttributes[IN2].ToDOMAnimatedString(aIn, this);
+}
+
+/* readonly attribute nsIDOMSVGAnimatedEnumeration mode; */
+NS_IMETHODIMP nsSVGFEBlendElement::GetMode(nsIDOMSVGAnimatedEnumeration * *aMode)
+{
+  return mEnumAttributes[MODE].ToDOMAnimatedEnum(aMode, this);
+}
+
+nsresult
+nsSVGFEBlendElement::Filter(nsSVGFilterInstance* aInstance,
+                            const nsTArray<const Image*>& aSources,
+                            const Image* aTarget,
+                            const nsIntRect& rect)
+{
+  CopyRect(aTarget, aSources[0], rect);
+
+  uint8_t* sourceData = aSources[1]->mImage->Data();
+  uint8_t* targetData = aTarget->mImage->Data();
+  uint32_t stride = aTarget->mImage->Stride();
+
+  uint16_t mode = mEnumAttributes[MODE].GetAnimValue();
+
+  for (int32_t x = rect.x; x < rect.XMost(); x++) {
+    for (int32_t y = rect.y; y < rect.YMost(); y++) {
+      uint32_t targIndex = y * stride + 4 * x;
+      uint32_t qa = targetData[targIndex + GFX_ARGB32_OFFSET_A];
+      uint32_t qb = sourceData[targIndex + GFX_ARGB32_OFFSET_A];
+      for (int32_t i = std::min(GFX_ARGB32_OFFSET_B, GFX_ARGB32_OFFSET_R);
+           i <= std::max(GFX_ARGB32_OFFSET_B, GFX_ARGB32_OFFSET_R); i++) {
+        uint32_t ca = targetData[targIndex + i];
+        uint32_t cb = sourceData[targIndex + i];
+        uint32_t val;
+        switch (mode) {
+          case nsSVGFEBlendElement::SVG_MODE_NORMAL:
+            val = (255 - qa) * cb + 255 * ca;
+            break;
+          case nsSVGFEBlendElement::SVG_MODE_MULTIPLY:
+            val = ((255 - qa) * cb + (255 - qb + cb) * ca);
+            break;
+          case nsSVGFEBlendElement::SVG_MODE_SCREEN:
+            val = 255 * (cb + ca) - ca * cb;
+            break;
+          case nsSVGFEBlendElement::SVG_MODE_DARKEN:
+            val = std::min((255 - qa) * cb + 255 * ca,
+                         (255 - qb) * ca + 255 * cb);
+            break;
+          case nsSVGFEBlendElement::SVG_MODE_LIGHTEN:
+            val = std::max((255 - qa) * cb + 255 * ca,
+                         (255 - qb) * ca + 255 * cb);
+            break;
+          default:
+            return NS_ERROR_FAILURE;
+            break;
+        }
+        val = std::min(val / 255, 255U);
+        targetData[targIndex + i] =  static_cast<uint8_t>(val);
+      }
+      uint32_t alpha = 255 * 255 - (255 - qa) * (255 - qb);
+      FAST_DIVIDE_BY_255(targetData[targIndex + GFX_ARGB32_OFFSET_A], alpha);
+    }
+  }
+  return NS_OK;
+}
+
+bool
+nsSVGFEBlendElement::AttributeAffectsRendering(int32_t aNameSpaceID,
+                                               nsIAtom* aAttribute) const
+{
+  return nsSVGFEBlendElementBase::AttributeAffectsRendering(aNameSpaceID, aAttribute) ||
+         (aNameSpaceID == kNameSpaceID_None &&
+          (aAttribute == nsGkAtoms::in ||
+           aAttribute == nsGkAtoms::in2 ||
+           aAttribute == nsGkAtoms::mode));
+}
+
+void
+nsSVGFEBlendElement::GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources)
+{
+  aSources.AppendElement(nsSVGStringInfo(&mStringAttributes[IN1], this));
+  aSources.AppendElement(nsSVGStringInfo(&mStringAttributes[IN2], this));
+}
+
+//----------------------------------------------------------------------
+// nsSVGElement methods
+
+nsSVGElement::EnumAttributesInfo
+nsSVGFEBlendElement::GetEnumInfo()
+{
+  return EnumAttributesInfo(mEnumAttributes, sEnumInfo,
+                            ArrayLength(sEnumInfo));
+}
+
+nsSVGElement::StringAttributesInfo
+nsSVGFEBlendElement::GetStringInfo()
+{
+  return StringAttributesInfo(mStringAttributes, sStringInfo,
+                              ArrayLength(sStringInfo));
+}
+
 //---------------------Color Matrix------------------------
 
 typedef nsSVGFE nsSVGFEColorMatrixElementBase;
 
 class nsSVGFEColorMatrixElement : public nsSVGFEColorMatrixElementBase,
                                   public nsIDOMSVGFEColorMatrixElement
 {
   friend nsresult NS_NewSVGFEColorMatrixElement(nsIContent **aResult,
--- a/content/svg/content/src/nsSVGFilters.h
+++ b/content/svg/content/src/nsSVGFilters.h
@@ -184,24 +184,17 @@ public:
 
   static nsIntRect GetMaxRect() {
     // Try to avoid overflow errors dealing with this rect. It will
     // be intersected with some other reasonable-sized rect eventually.
     return nsIntRect(INT32_MIN/2, INT32_MIN/2, INT32_MAX, INT32_MAX);
   }
 
   operator nsISupports*() { return static_cast<nsIContent*>(this); }
-
-  // WebIDL
-  already_AddRefed<mozilla::dom::SVGAnimatedLength> X();
-  already_AddRefed<mozilla::dom::SVGAnimatedLength> Y();
-  already_AddRefed<mozilla::dom::SVGAnimatedLength> Width();
-  already_AddRefed<mozilla::dom::SVGAnimatedLength> Height();
-  already_AddRefed<nsIDOMSVGAnimatedString> Result();
-
+  
 protected:
   virtual bool OperatesOnPremultipledAlpha(int32_t) { return true; }
 
   // Called either with aInputIndex >=0 in which case this is
   // testing whether the input 'aInputIndex' should be SRGB, or
   // if aInputIndex is -1 returns true if the output will be SRGB
   virtual bool OperatesOnSRGB(nsSVGFilterInstance* aInstance,
                                 int32_t aInputIndex, Image* aImage) {
@@ -212,17 +205,17 @@ protected:
     return style->StyleSVG()->mColorInterpolationFilters ==
              NS_STYLE_COLOR_INTERPOLATION_SRGB;
   }
 
   // nsSVGElement specializations:
   virtual LengthAttributesInfo GetLengthInfo();
 
   // nsIDOMSVGFitlerPrimitiveStandardAttributes values
-  enum { ATTR_X, ATTR_Y, ATTR_WIDTH, ATTR_HEIGHT };
+  enum { X, Y, WIDTH, HEIGHT };
   nsSVGLength2 mLengthAttributes[4];
   static LengthInfo sLengthInfo[4];
 };
 
 typedef nsSVGFE nsSVGFEImageElementBase;
 
 class nsSVGFEImageElement : public nsSVGFEImageElementBase,
                             public nsIDOMSVGFEImageElement,
@@ -314,25 +307,9 @@ protected:
 
 public:
   // returns true if changes to the attribute should cause us to
   // repaint the filter
   virtual bool AttributeAffectsRendering(
           int32_t aNameSpaceID, nsIAtom* aAttribute) const = 0;
 };
 
-void
-CopyDataRect(uint8_t *aDest, const uint8_t *aSrc, uint32_t aStride,
-             const nsIntRect& aDataRect);
-
-inline void
-CopyRect(const nsSVGFE::Image* aDest, const nsSVGFE::Image* aSrc, const nsIntRect& aDataRect)
-{
-  NS_ASSERTION(aDest->mImage->Stride() == aSrc->mImage->Stride(), "stride mismatch");
-  NS_ASSERTION(aDest->mImage->GetSize() == aSrc->mImage->GetSize(), "size mismatch");
-  NS_ASSERTION(nsIntRect(0, 0, aDest->mImage->Width(), aDest->mImage->Height()).Contains(aDataRect),
-               "aDataRect out of bounds");
-
-  CopyDataRect(aDest->mImage->Data(), aSrc->mImage->Data(),
-               aSrc->mImage->Stride(), aDataRect);
-}
-
 #endif
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -811,16 +811,18 @@ static nsDOMClassInfoData sClassInfoData
 
   // SVG document
   NS_DEFINE_CLASSINFO_DATA(SVGDocument, nsDocumentSH,
                            DOCUMENT_SCRIPTABLE_FLAGS)
 
   // SVG element classes
   NS_DEFINE_CLASSINFO_DATA(TimeEvent, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
+  NS_DEFINE_CLASSINFO_DATA(SVGFEBlendElement, nsElementSH,
+                           ELEMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(SVGFEColorMatrixElement, nsElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(SVGFEComponentTransferElement, nsElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(SVGFECompositeElement, nsElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(SVGFEConvolveMatrixElement, nsElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
@@ -2268,16 +2270,22 @@ nsDOMClassInfo::Init()
   DOM_CLASSINFO_MAP_END
 
   // SVG element classes
   DOM_CLASSINFO_MAP_BEGIN(TimeEvent, nsIDOMTimeEvent)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMTimeEvent)
     DOM_CLASSINFO_EVENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
+  DOM_CLASSINFO_MAP_BEGIN(SVGFEBlendElement, nsIDOMSVGFEBlendElement)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGFEBlendElement)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGFilterPrimitiveStandardAttributes)
+    DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
+  DOM_CLASSINFO_MAP_END
+
   DOM_CLASSINFO_MAP_BEGIN(SVGFEColorMatrixElement, nsIDOMSVGFEColorMatrixElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGFEColorMatrixElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGFilterPrimitiveStandardAttributes)
     DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(SVGFEComponentTransferElement, nsIDOMSVGFEComponentTransferElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGFEComponentTransferElement)
--- a/dom/base/nsDOMClassInfoClasses.h
+++ b/dom/base/nsDOMClassInfoClasses.h
@@ -116,16 +116,17 @@ DOMCI_CLASS(CSSSupportsRule)
 
 DOMCI_CLASS(BeforeUnloadEvent)
 
 // The SVG document
 DOMCI_CLASS(SVGDocument)
 
 // SVG element classes
 DOMCI_CLASS(TimeEvent)
+DOMCI_CLASS(SVGFEBlendElement)
 DOMCI_CLASS(SVGFEColorMatrixElement)
 DOMCI_CLASS(SVGFEComponentTransferElement)
 DOMCI_CLASS(SVGFECompositeElement)
 DOMCI_CLASS(SVGFEConvolveMatrixElement)
 DOMCI_CLASS(SVGFEDiffuseLightingElement)
 DOMCI_CLASS(SVGFEDisplacementMapElement)
 DOMCI_CLASS(SVGFEDistantLightElement)
 DOMCI_CLASS(SVGFEFloodElement)
--- a/dom/interfaces/svg/nsIDOMSVGFilters.idl
+++ b/dom/interfaces/svg/nsIDOMSVGFilters.idl
@@ -16,16 +16,31 @@ interface nsIDOMSVGFilterPrimitiveStanda
 { 
     readonly attribute nsIDOMSVGAnimatedLength      x;
     readonly attribute nsIDOMSVGAnimatedLength      y;
     readonly attribute nsIDOMSVGAnimatedLength      width;
     readonly attribute nsIDOMSVGAnimatedLength      height;
     readonly attribute nsIDOMSVGAnimatedString      result;
 };
 
+[scriptable, uuid(02DB0A51-087B-4EA4-ABC4-3DCAB65BFE83)]
+interface nsIDOMSVGFEBlendElement : nsIDOMSVGFilterPrimitiveStandardAttributes
+{
+    const unsigned short SVG_MODE_UNKNOWN   = 0;
+    const unsigned short SVG_MODE_NORMAL    = 1;
+    const unsigned short SVG_MODE_MULTIPLY  = 2;
+    const unsigned short SVG_MODE_SCREEN    = 3;
+    const unsigned short SVG_MODE_DARKEN    = 4;
+    const unsigned short SVG_MODE_LIGHTEN   = 5;
+
+    readonly attribute nsIDOMSVGAnimatedString        in1;
+    readonly attribute nsIDOMSVGAnimatedString        in2;
+    readonly attribute nsIDOMSVGAnimatedEnumeration   mode;
+};
+
 [scriptable, uuid(BB966D00-CF60-4696-9954-43525401E209)]
 interface nsIDOMSVGFEColorMatrixElement : nsIDOMSVGFilterPrimitiveStandardAttributes
 {
     // Color Matrix Types
     const unsigned short SVG_FECOLORMATRIX_TYPE_UNKNOWN            = 0;
     const unsigned short SVG_FECOLORMATRIX_TYPE_MATRIX             = 1;
     const unsigned short SVG_FECOLORMATRIX_TYPE_SATURATE           = 2;
     const unsigned short SVG_FECOLORMATRIX_TYPE_HUE_ROTATE         = 3;
deleted file mode 100644
--- a/dom/webidl/SVGFEBlendElement.webidl
+++ /dev/null
@@ -1,31 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * The origin of this IDL file is
- * http://www.w3.org/TR/SVG2/
- *
- * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
- * liability, trademark and document use rules apply.
- */
-
-interface SVGAnimatedEnumeration;
-interface SVGAnimatedString;
-
-interface SVGFEBlendElement : SVGElement {
-
-  // Blend Mode Types
-  const unsigned short SVG_FEBLEND_MODE_UNKNOWN = 0;
-  const unsigned short SVG_FEBLEND_MODE_NORMAL = 1;
-  const unsigned short SVG_FEBLEND_MODE_MULTIPLY = 2;
-  const unsigned short SVG_FEBLEND_MODE_SCREEN = 3;
-  const unsigned short SVG_FEBLEND_MODE_DARKEN = 4;
-  const unsigned short SVG_FEBLEND_MODE_LIGHTEN = 5;
-
-  readonly attribute SVGAnimatedString in1;
-  readonly attribute SVGAnimatedString in2;
-  readonly attribute SVGAnimatedEnumeration mode;
-};
-
-SVGFEBlendElement implements SVGFilterPrimitiveStandardAttributes;
deleted file mode 100644
--- a/dom/webidl/SVGFilterPrimitiveStandardAttributes.webidl
+++ /dev/null
@@ -1,22 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * The origin of this IDL file is
- * http://www.w3.org/TR/SVG2/
- *
- * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
- * liability, trademark and document use rules apply.
- */
-
-interface SVGAnimatedString;
-
-[NoInterfaceObject]
-interface SVGFilterPrimitiveStandardAttributes {
-  readonly attribute SVGAnimatedLength x;
-  readonly attribute SVGAnimatedLength y;
-  readonly attribute SVGAnimatedLength width;
-  readonly attribute SVGAnimatedLength height;
-  readonly attribute SVGAnimatedString result;
-};
--- a/dom/webidl/WebIDL.mk
+++ b/dom/webidl/WebIDL.mk
@@ -154,18 +154,16 @@ webidl_files = \
   SVGCircleElement.webidl \
   SVGClipPathElement.webidl \
   SVGComponentTransferFunctionElement.webidl \
   SVGDefsElement.webidl \
   SVGDescElement.webidl \
   SVGElement.webidl \
   SVGEllipseElement.webidl \
   SVGFilterElement.webidl \
-  SVGFilterPrimitiveStandardAttributes.webidl \
-  SVGFEBlendElement.webidl \
   SVGFEFuncAElement.webidl \
   SVGFEFuncBElement.webidl \
   SVGFEFuncGElement.webidl \
   SVGFEFuncRElement.webidl \
   SVGFitToViewBox.webidl \
   SVGForeignObjectElement.webidl \
   SVGGElement.webidl \
   SVGGradientElement.webidl \
--- a/layout/svg/nsSVGFilterInstance.cpp
+++ b/layout/svg/nsSVGFilterInstance.cpp
@@ -120,26 +120,26 @@ nsSVGFilterInstance::ComputeFilterPrimit
               aPrimitive->mInputs[i]->mImage.mFilterPrimitiveSubregion);
     }
   } else {
     defaultFilterSubregion =
       gfxRect(0, 0, mFilterSpaceSize.width, mFilterSpaceSize.height);
   }
 
   gfxRect feArea = nsSVGUtils::GetRelativeRect(mPrimitiveUnits,
-    &fE->mLengthAttributes[nsSVGFE::ATTR_X], mTargetBBox, mTargetFrame);
+    &fE->mLengthAttributes[nsSVGFE::X], mTargetBBox, mTargetFrame);
   gfxRect region = UserSpaceToFilterSpace(feArea);
 
-  if (!fE->mLengthAttributes[nsSVGFE::ATTR_X].IsExplicitlySet())
+  if (!fE->mLengthAttributes[nsSVGFE::X].IsExplicitlySet())
     region.x = defaultFilterSubregion.X();
-  if (!fE->mLengthAttributes[nsSVGFE::ATTR_Y].IsExplicitlySet())
+  if (!fE->mLengthAttributes[nsSVGFE::Y].IsExplicitlySet())
     region.y = defaultFilterSubregion.Y();
-  if (!fE->mLengthAttributes[nsSVGFE::ATTR_WIDTH].IsExplicitlySet())
+  if (!fE->mLengthAttributes[nsSVGFE::WIDTH].IsExplicitlySet())
     region.width = defaultFilterSubregion.Width();
-  if (!fE->mLengthAttributes[nsSVGFE::ATTR_HEIGHT].IsExplicitlySet())
+  if (!fE->mLengthAttributes[nsSVGFE::HEIGHT].IsExplicitlySet())
     region.height = defaultFilterSubregion.Height();
 
   // We currently require filter primitive subregions to be pixel-aligned.
   // Following the spec, any pixel partially in the region is included
   // in the region.
   region.RoundOut();
   aPrimitive->mImage.mFilterPrimitiveSubregion = region;
 }