Bug 1417699 - Remove PrimitiveType enum r=mstange
authorDoug Thayer <dothayer@mozilla.com>
Wed, 19 Sep 2018 17:18:44 +0000
changeset 495720 87694c630c01f0ce1bd244d6cb53cde3b6785100
parent 495719 4f3360c4f1049712a9ab641078838bc0e197e0c4
child 495721 3cb7ca8de681efd74b96e1d2c377c504e97a0348
push id1864
push userffxbld-merge
push dateMon, 03 Dec 2018 15:51:40 +0000
treeherdermozilla-release@f040763d99ad [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange
bugs1417699
milestone64.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1417699 - Remove PrimitiveType enum r=mstange Ran into a couple of test failures because I was leaving mAttributes empty for empty things like MergeAttributes, and only setting mType. Since mType is now redundant though, and since it's the only use of PrimitiveType, I figured I'd just remove it entirely. Depends on D4900 Differential Revision: https://phabricator.services.mozilla.com/D6209
dom/svg/SVGFEBlendElement.cpp
dom/svg/SVGFEColorMatrixElement.cpp
dom/svg/SVGFEComponentTransferElement.cpp
dom/svg/SVGFECompositeElement.cpp
dom/svg/SVGFEConvolveMatrixElement.cpp
dom/svg/SVGFEDiffuseLightingElement.cpp
dom/svg/SVGFEDisplacementMapElement.cpp
dom/svg/SVGFEDropShadowElement.cpp
dom/svg/SVGFEFloodElement.cpp
dom/svg/SVGFEGaussianBlurElement.cpp
dom/svg/SVGFEImageElement.cpp
dom/svg/SVGFEMergeElement.cpp
dom/svg/SVGFEMorphologyElement.cpp
dom/svg/SVGFEOffsetElement.cpp
dom/svg/SVGFESpecularLightingElement.cpp
dom/svg/SVGFETileElement.cpp
dom/svg/SVGFETurbulenceElement.cpp
gfx/ipc/GfxMessageUtils.h
gfx/src/FilterSupport.cpp
gfx/src/FilterSupport.h
layout/svg/nsCSSFilterInstance.cpp
layout/svg/nsCSSFilterInstance.h
layout/svg/nsSVGFilterInstance.cpp
--- a/dom/svg/SVGFEBlendElement.cpp
+++ b/dom/svg/SVGFEBlendElement.cpp
@@ -84,21 +84,19 @@ SVGFEBlendElement::Mode()
 
 FilterPrimitiveDescription
 SVGFEBlendElement::GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
                                            const IntRect& aFilterSubregion,
                                            const nsTArray<bool>& aInputsAreTainted,
                                            nsTArray<RefPtr<SourceSurface>>& aInputImages)
 {
   uint32_t mode = mEnumAttributes[MODE].GetAnimValue();
-  FilterPrimitiveDescription descr(PrimitiveType::Blend);
   BlendAttributes attributes;
   attributes.mBlendMode = mode;
-  descr.Attributes() = AsVariant(attributes);
-  return descr;
+  return FilterPrimitiveDescription(AsVariant(std::move(attributes)));
 }
 
 bool
 SVGFEBlendElement::AttributeAffectsRendering(int32_t aNameSpaceID,
                                              nsAtom* aAttribute) const
 {
   return SVGFEBlendElementBase::AttributeAffectsRendering(aNameSpaceID, aAttribute) ||
          (aNameSpaceID == kNameSpaceID_None &&
--- a/dom/svg/SVGFEColorMatrixElement.cpp
+++ b/dom/svg/SVGFEColorMatrixElement.cpp
@@ -89,17 +89,16 @@ FilterPrimitiveDescription
 SVGFEColorMatrixElement::GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
                                                  const IntRect& aFilterSubregion,
                                                  const nsTArray<bool>& aInputsAreTainted,
                                                  nsTArray<RefPtr<SourceSurface>>& aInputImages)
 {
   uint32_t type = mEnumAttributes[TYPE].GetAnimValue();
   const SVGNumberList &values = mNumberListAttributes[VALUES].GetAnimValue();
 
-  FilterPrimitiveDescription descr(PrimitiveType::ColorMatrix);
   ColorMatrixAttributes atts;
   if (!mNumberListAttributes[VALUES].IsExplicitlySet() &&
       (type == SVG_FECOLORMATRIX_TYPE_MATRIX ||
        type == SVG_FECOLORMATRIX_TYPE_SATURATE ||
        type == SVG_FECOLORMATRIX_TYPE_HUE_ROTATE)) {
     atts.mType = (uint32_t)SVG_FECOLORMATRIX_TYPE_MATRIX;
     static const float identityMatrix[] =
       { 1, 0, 0, 0, 0,
@@ -109,18 +108,17 @@ SVGFEColorMatrixElement::GetPrimitiveDes
     atts.mValues.AppendElements(identityMatrix, 20);
   } else {
     atts.mType = type;
     if (values.Length()) {
       atts.mValues.AppendElements(&values[0], values.Length());
     }
   }
 
-  descr.Attributes() = AsVariant(std::move(atts));
-  return descr;
+  return FilterPrimitiveDescription(AsVariant(std::move(atts)));
 }
 
 bool
 SVGFEColorMatrixElement::AttributeAffectsRendering(int32_t aNameSpaceID,
                                                    nsAtom* aAttribute) const
 {
   return SVGFEColorMatrixElementBase::AttributeAffectsRendering(aNameSpaceID, aAttribute) ||
          (aNameSpaceID == kNameSpaceID_None &&
--- a/dom/svg/SVGFEComponentTransferElement.cpp
+++ b/dom/svg/SVGFEComponentTransferElement.cpp
@@ -67,28 +67,26 @@ SVGFEComponentTransferElement::GetPrimit
     RefPtr<SVGComponentTransferFunctionElement> child;
     CallQueryInterface(childContent,
             (SVGComponentTransferFunctionElement**)getter_AddRefs(child));
     if (child) {
       childForChannel[child->GetChannel()] = child;
     }
   }
 
-  FilterPrimitiveDescription descr(PrimitiveType::ComponentTransfer);
   ComponentTransferAttributes atts;
   for (int32_t i = 0; i < 4; i++) {
     if (childForChannel[i]) {
       childForChannel[i]->ComputeAttributes(i, atts);
     } else {
       atts.mTypes[i] =
         (uint8_t)SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY;
     }
   }
-  descr.Attributes() = AsVariant(std::move(atts));
-  return descr;
+  return FilterPrimitiveDescription(AsVariant(std::move(atts)));
 }
 
 bool
 SVGFEComponentTransferElement::AttributeAffectsRendering(int32_t aNameSpaceID,
                                                          nsAtom* aAttribute) const
 {
   return SVGFEComponentTransferElementBase::AttributeAffectsRendering(aNameSpaceID, aAttribute) ||
          (aNameSpaceID == kNameSpaceID_None &&
--- a/dom/svg/SVGFECompositeElement.cpp
+++ b/dom/svg/SVGFECompositeElement.cpp
@@ -110,29 +110,27 @@ SVGFECompositeElement::SetK(float k1, fl
 }
 
 FilterPrimitiveDescription
 SVGFECompositeElement::GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
                                                const IntRect& aFilterSubregion,
                                                const nsTArray<bool>& aInputsAreTainted,
                                                nsTArray<RefPtr<SourceSurface>>& aInputImages)
 {
-  FilterPrimitiveDescription descr(PrimitiveType::Composite);
   CompositeAttributes atts;
   uint32_t op = mEnumAttributes[OPERATOR].GetAnimValue();
   atts.mOperator = op;
 
   if (op == SVG_FECOMPOSITE_OPERATOR_ARITHMETIC) {
     float k[4];
     GetAnimatedNumberValues(k, k+1, k+2, k+3, nullptr);
     atts.mCoefficients.AppendElements(k, 4);
   }
 
-  descr.Attributes() = AsVariant(std::move(atts));
-  return descr;
+  return FilterPrimitiveDescription(AsVariant(std::move(atts)));
 }
 
 bool
 SVGFECompositeElement::AttributeAffectsRendering(int32_t aNameSpaceID,
                                                  nsAtom* aAttribute) const
 {
   return SVGFECompositeElementBase::AttributeAffectsRendering(aNameSpaceID, aAttribute) ||
          (aNameSpaceID == kNameSpaceID_None &&
--- a/dom/svg/SVGFEConvolveMatrixElement.cpp
+++ b/dom/svg/SVGFEConvolveMatrixElement.cpp
@@ -167,17 +167,17 @@ SVGFEConvolveMatrixElement::GetSourceIma
 }
 
 FilterPrimitiveDescription
 SVGFEConvolveMatrixElement::GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
                                                     const IntRect& aFilterSubregion,
                                                     const nsTArray<bool>& aInputsAreTainted,
                                                     nsTArray<RefPtr<SourceSurface>>& aInputImages)
 {
-  FilterPrimitiveDescription failureDescription(PrimitiveType::Empty);
+  FilterPrimitiveDescription failureDescription;
 
   const SVGNumberList &kernelMatrix =
     mNumberListAttributes[KERNELMATRIX].GetAnimValue();
   uint32_t kmLength = kernelMatrix.Length();
 
   int32_t orderX = mIntegerPairAttributes[ORDER].GetAnimValue(nsSVGIntegerPair::eFirst);
   int32_t orderY = mIntegerPairAttributes[ORDER].GetAnimValue(nsSVGIntegerPair::eSecond);
 
@@ -233,29 +233,27 @@ SVGFEConvolveMatrixElement::GetPrimitive
     GetKernelUnitLength(aInstance, &mNumberPairAttributes[KERNEL_UNIT_LENGTH]);
 
   if (kernelUnitLength.width <= 0 || kernelUnitLength.height <= 0) {
     // According to spec, A negative or zero value is an error. See link below for details.
     // https://www.w3.org/TR/SVG/filters.html#feConvolveMatrixElementKernelUnitLengthAttribute
     return failureDescription;
   }
 
-  FilterPrimitiveDescription descr(PrimitiveType::ConvolveMatrix);
   ConvolveMatrixAttributes atts;
   atts.mKernelSize = IntSize(orderX, orderY);
   atts.mKernelMatrix.AppendElements(&kernelMatrix[0], kmLength);
   atts.mDivisor = divisor;
   atts.mBias = bias;
   atts.mTarget = IntPoint(targetX, targetY);
   atts.mEdgeMode = edgeMode;
   atts.mKernelUnitLength = kernelUnitLength;
   atts.mPreserveAlpha = preserveAlpha;
 
-  descr.Attributes() = AsVariant(std::move(atts));
-  return descr;
+  return FilterPrimitiveDescription(AsVariant(std::move(atts)));
 }
 
 bool
 SVGFEConvolveMatrixElement::AttributeAffectsRendering(int32_t aNameSpaceID,
                                                       nsAtom* aAttribute) const
 {
   return SVGFEConvolveMatrixElementBase::AttributeAffectsRendering(aNameSpaceID, aAttribute) ||
          (aNameSpaceID == kNameSpaceID_None &&
--- a/dom/svg/SVGFEDiffuseLightingElement.cpp
+++ b/dom/svg/SVGFEDiffuseLightingElement.cpp
@@ -64,25 +64,23 @@ SVGFEDiffuseLightingElement::KernelUnitL
 FilterPrimitiveDescription
 SVGFEDiffuseLightingElement::GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
                                                      const IntRect& aFilterSubregion,
                                                      const nsTArray<bool>& aInputsAreTainted,
                                                      nsTArray<RefPtr<SourceSurface>>& aInputImages)
 {
   float diffuseConstant = mNumberAttributes[DIFFUSE_CONSTANT].GetAnimValue();
 
-  FilterPrimitiveDescription descr(PrimitiveType::DiffuseLighting);
   DiffuseLightingAttributes atts;
   atts.mLightingConstant = diffuseConstant;
   if (!AddLightingAttributes(&atts, aInstance)) {
-    return FilterPrimitiveDescription(PrimitiveType::Empty);
+    return FilterPrimitiveDescription();
   }
 
-  descr.Attributes() = AsVariant(std::move(atts));
-  return descr;
+  return FilterPrimitiveDescription(AsVariant(std::move(atts)));
 }
 
 bool
 SVGFEDiffuseLightingElement::AttributeAffectsRendering(int32_t aNameSpaceID,
                                                        nsAtom* aAttribute) const
 {
   return SVGFEDiffuseLightingElementBase::AttributeAffectsRendering(aNameSpaceID, aAttribute) ||
          (aNameSpaceID == kNameSpaceID_None &&
--- a/dom/svg/SVGFEDisplacementMapElement.cpp
+++ b/dom/svg/SVGFEDisplacementMapElement.cpp
@@ -95,34 +95,30 @@ FilterPrimitiveDescription
 SVGFEDisplacementMapElement::GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
                                                      const IntRect& aFilterSubregion,
                                                      const nsTArray<bool>& aInputsAreTainted,
                                                      nsTArray<RefPtr<SourceSurface>>& aInputImages)
 {
   if (aInputsAreTainted[1]) {
     // If the map is tainted, refuse to apply the effect and act as a
     // pass-through filter instead, as required by the spec.
-    FilterPrimitiveDescription descr(PrimitiveType::Offset);
     OffsetAttributes atts;
     atts.mValue = IntPoint(0, 0);
-    descr.Attributes() = AsVariant(std::move(atts));
-    return descr;
+    return FilterPrimitiveDescription(AsVariant(std::move(atts)));
   }
 
   float scale = aInstance->GetPrimitiveNumber(SVGContentUtils::XY,
                                               &mNumberAttributes[SCALE]);
   uint32_t xChannel = mEnumAttributes[CHANNEL_X].GetAnimValue();
   uint32_t yChannel = mEnumAttributes[CHANNEL_Y].GetAnimValue();
-  FilterPrimitiveDescription descr(PrimitiveType::DisplacementMap);
   DisplacementMapAttributes atts;
   atts.mScale = scale;
   atts.mXChannel = xChannel;
   atts.mYChannel = yChannel;
-  descr.Attributes() = AsVariant(std::move(atts));
-  return descr;
+  return FilterPrimitiveDescription(AsVariant(std::move(atts)));
 }
 
 bool
 SVGFEDisplacementMapElement::AttributeAffectsRendering(int32_t aNameSpaceID,
                                                        nsAtom* aAttribute) const
 {
   return SVGFEDisplacementMapElementBase::AttributeAffectsRendering(aNameSpaceID, aAttribute) ||
          (aNameSpaceID == kNameSpaceID_None &&
--- a/dom/svg/SVGFEDropShadowElement.cpp
+++ b/dom/svg/SVGFEDropShadowElement.cpp
@@ -90,40 +90,38 @@ SVGFEDropShadowElement::GetPrimitiveDesc
 {
   float stdX = aInstance->GetPrimitiveNumber(SVGContentUtils::X,
                                              &mNumberPairAttributes[STD_DEV],
                                              nsSVGNumberPair::eFirst);
   float stdY = aInstance->GetPrimitiveNumber(SVGContentUtils::Y,
                                              &mNumberPairAttributes[STD_DEV],
                                              nsSVGNumberPair::eSecond);
   if (stdX < 0 || stdY < 0) {
-    return FilterPrimitiveDescription(PrimitiveType::Empty);
+    return FilterPrimitiveDescription();
   }
 
   IntPoint offset(int32_t(aInstance->GetPrimitiveNumber(
                             SVGContentUtils::X, &mNumberAttributes[DX])),
                   int32_t(aInstance->GetPrimitiveNumber(
                             SVGContentUtils::Y, &mNumberAttributes[DY])));
 
-  FilterPrimitiveDescription descr(PrimitiveType::DropShadow);
   DropShadowAttributes atts;
   atts.mStdDeviation = Size(stdX, stdY);
   atts.mOffset = offset;
 
   nsIFrame* frame = GetPrimaryFrame();
   if (frame) {
     const nsStyleSVGReset* styleSVGReset = frame->Style()->StyleSVGReset();
     Color color(Color::FromABGR(styleSVGReset->mFloodColor.CalcColor(frame)));
     color.a *= styleSVGReset->mFloodOpacity;
     atts.mColor = color;
   } else {
     atts.mColor = Color();
   }
-  descr.Attributes() = AsVariant(std::move(atts));
-  return descr;
+  return FilterPrimitiveDescription(AsVariant(std::move(atts)));
 }
 
 bool
 SVGFEDropShadowElement::AttributeAffectsRendering(int32_t aNameSpaceID,
                                                   nsAtom* aAttribute) const
 {
   return SVGFEDropShadowElementBase::AttributeAffectsRendering(aNameSpaceID, aAttribute) ||
          (aNameSpaceID == kNameSpaceID_None &&
--- a/dom/svg/SVGFEFloodElement.cpp
+++ b/dom/svg/SVGFEFloodElement.cpp
@@ -35,29 +35,27 @@ nsSVGElement::StringInfo SVGFEFloodEleme
 NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGFEFloodElement)
 
 FilterPrimitiveDescription
 SVGFEFloodElement::GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
                                            const IntRect& aFilterSubregion,
                                            const nsTArray<bool>& aInputsAreTainted,
                                            nsTArray<RefPtr<SourceSurface>>& aInputImages)
 {
-  FilterPrimitiveDescription descr(PrimitiveType::Flood);
   FloodAttributes atts;
   nsIFrame* frame = GetPrimaryFrame();
   if (frame) {
     const nsStyleSVGReset* styleSVGReset = frame->Style()->StyleSVGReset();
     Color color(Color::FromABGR(styleSVGReset->mFloodColor.CalcColor(frame)));
     color.a *= styleSVGReset->mFloodOpacity;
     atts.mColor = color;
   } else {
     atts.mColor = Color();
   }
-  descr.Attributes() = AsVariant(std::move(atts));
-  return descr;
+  return FilterPrimitiveDescription(AsVariant(std::move(atts)));
 }
 
 //----------------------------------------------------------------------
 // nsIContent methods
 
 NS_IMETHODIMP_(bool)
 SVGFEFloodElement::IsAttributeMapped(const nsAtom* name) const
 {
--- a/dom/svg/SVGFEGaussianBlurElement.cpp
+++ b/dom/svg/SVGFEGaussianBlurElement.cpp
@@ -72,24 +72,22 @@ SVGFEGaussianBlurElement::GetPrimitiveDe
 {
   float stdX = aInstance->GetPrimitiveNumber(SVGContentUtils::X,
                                              &mNumberPairAttributes[STD_DEV],
                                              nsSVGNumberPair::eFirst);
   float stdY = aInstance->GetPrimitiveNumber(SVGContentUtils::Y,
                                              &mNumberPairAttributes[STD_DEV],
                                              nsSVGNumberPair::eSecond);
   if (stdX < 0 || stdY < 0) {
-    return FilterPrimitiveDescription(PrimitiveType::Empty);
+    return FilterPrimitiveDescription();
   }
 
-  FilterPrimitiveDescription descr(PrimitiveType::GaussianBlur);
   GaussianBlurAttributes atts;
   atts.mStdDeviation = Size(stdX, stdY);
-  descr.Attributes() = AsVariant(std::move(atts));
-  return descr;
+  return FilterPrimitiveDescription(AsVariant(std::move(atts)));
 }
 
 bool
 SVGFEGaussianBlurElement::AttributeAffectsRendering(int32_t aNameSpaceID,
                                                     nsAtom* aAttribute) const
 {
   return SVGFEGaussianBlurElementBase::AttributeAffectsRendering(aNameSpaceID, aAttribute) ||
          (aNameSpaceID == kNameSpaceID_None &&
--- a/dom/svg/SVGFEImageElement.cpp
+++ b/dom/svg/SVGFEImageElement.cpp
@@ -212,17 +212,17 @@ SVGFEImageElement::Href()
 FilterPrimitiveDescription
 SVGFEImageElement::GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
                                            const IntRect& aFilterSubregion,
                                            const nsTArray<bool>& aInputsAreTainted,
                                            nsTArray<RefPtr<SourceSurface>>& aInputImages)
 {
   nsIFrame* frame = GetPrimaryFrame();
   if (!frame) {
-    return FilterPrimitiveDescription(PrimitiveType::Empty);
+    return FilterPrimitiveDescription();
   }
 
   nsCOMPtr<imgIRequest> currentRequest;
   GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
              getter_AddRefs(currentRequest));
 
   nsCOMPtr<imgIContainer> imageContainer;
   if (currentRequest) {
@@ -231,44 +231,41 @@ SVGFEImageElement::GetPrimitiveDescripti
 
   RefPtr<SourceSurface> image;
   if (imageContainer) {
     uint32_t flags = imgIContainer::FLAG_SYNC_DECODE | imgIContainer::FLAG_ASYNC_NOTIFY;
     image = imageContainer->GetFrame(imgIContainer::FRAME_CURRENT, flags);
   }
 
   if (!image) {
-    return FilterPrimitiveDescription(PrimitiveType::Empty);
+    return FilterPrimitiveDescription();
   }
 
   IntSize nativeSize;
   imageContainer->GetWidth(&nativeSize.width);
   imageContainer->GetHeight(&nativeSize.height);
 
   Matrix viewBoxTM =
     SVGContentUtils::GetViewBoxTransform(aFilterSubregion.width, aFilterSubregion.height,
                                          0, 0, nativeSize.width, nativeSize.height,
                                          mPreserveAspectRatio);
   Matrix TM = viewBoxTM;
   TM.PostTranslate(aFilterSubregion.x, aFilterSubregion.y);
 
   SamplingFilter samplingFilter = nsLayoutUtils::GetSamplingFilterForFrame(frame);
 
-  FilterPrimitiveDescription descr(PrimitiveType::Image);
   ImageAttributes atts;
   atts.mFilter = (uint32_t)samplingFilter;
   atts.mTransform = TM;
 
   // Append the image to aInputImages and store its index in the description.
   size_t imageIndex = aInputImages.Length();
   aInputImages.AppendElement(image);
   atts.mInputIndex = (uint32_t)imageIndex;
-  descr.Attributes() = AsVariant(std::move(atts));
-
-  return descr;
+  return FilterPrimitiveDescription(AsVariant(std::move(atts)));
 }
 
 bool
 SVGFEImageElement::AttributeAffectsRendering(int32_t aNameSpaceID,
                                              nsAtom* aAttribute) const
 {
   // nsGkAtoms::href is deliberately omitted as the frame has special
   // handling to load the image
--- a/dom/svg/SVGFEMergeElement.cpp
+++ b/dom/svg/SVGFEMergeElement.cpp
@@ -29,17 +29,17 @@ nsSVGElement::StringInfo SVGFEMergeEleme
 NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGFEMergeElement)
 
 FilterPrimitiveDescription
 SVGFEMergeElement::GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
                                            const IntRect& aFilterSubregion,
                                            const nsTArray<bool>& aInputsAreTainted,
                                            nsTArray<RefPtr<SourceSurface>>& aInputImages)
 {
-  return FilterPrimitiveDescription(PrimitiveType::Merge);
+  return FilterPrimitiveDescription(AsVariant(MergeAttributes()));
 }
 
 void
 SVGFEMergeElement::GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources)
 {
   for (nsIContent* child = nsINode::GetFirstChild();
        child;
        child = child->GetNextSibling()) {
--- a/dom/svg/SVGFEMorphologyElement.cpp
+++ b/dom/svg/SVGFEMorphologyElement.cpp
@@ -115,22 +115,20 @@ SVGFEMorphologyElement::GetRXY(int32_t *
 FilterPrimitiveDescription
 SVGFEMorphologyElement::GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
                                                 const IntRect& aFilterSubregion,
                                                 const nsTArray<bool>& aInputsAreTainted,
                                                 nsTArray<RefPtr<SourceSurface>>& aInputImages)
 {
   int32_t rx, ry;
   GetRXY(&rx, &ry, *aInstance);
-  FilterPrimitiveDescription descr(PrimitiveType::Morphology);
   MorphologyAttributes atts;
   atts.mRadii = Size(rx, ry);
   atts.mOperator = (uint32_t)mEnumAttributes[OPERATOR].GetAnimValue();
-  descr.Attributes() = AsVariant(std::move(atts));
-  return descr;
+  return FilterPrimitiveDescription(AsVariant(std::move(atts)));
 }
 
 bool
 SVGFEMorphologyElement::AttributeAffectsRendering(int32_t aNameSpaceID,
                                                   nsAtom* aAttribute) const
 {
   return SVGFEMorphologyElementBase::AttributeAffectsRendering(aNameSpaceID, aAttribute) ||
          (aNameSpaceID == kNameSpaceID_None &&
--- a/dom/svg/SVGFEOffsetElement.cpp
+++ b/dom/svg/SVGFEOffsetElement.cpp
@@ -61,25 +61,23 @@ SVGFEOffsetElement::Dy()
 }
 
 FilterPrimitiveDescription
 SVGFEOffsetElement::GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
                                             const IntRect& aFilterSubregion,
                                             const nsTArray<bool>& aInputsAreTainted,
                                             nsTArray<RefPtr<SourceSurface>>& aInputImages)
 {
-  FilterPrimitiveDescription descr(PrimitiveType::Offset);
   OffsetAttributes atts;
   IntPoint offset(int32_t(aInstance->GetPrimitiveNumber(
                             SVGContentUtils::X, &mNumberAttributes[DX])),
                   int32_t(aInstance->GetPrimitiveNumber(
                             SVGContentUtils::Y, &mNumberAttributes[DY])));
   atts.mValue = offset;
-  descr.Attributes() = AsVariant(std::move(atts));
-  return descr;
+  return FilterPrimitiveDescription(AsVariant(std::move(atts)));
 }
 
 bool
 SVGFEOffsetElement::AttributeAffectsRendering(int32_t aNameSpaceID,
                                               nsAtom* aAttribute) const
 {
   return SVGFEOffsetElementBase::AttributeAffectsRendering(aNameSpaceID, aAttribute) ||
          (aNameSpaceID == kNameSpaceID_None &&
--- a/dom/svg/SVGFESpecularLightingElement.cpp
+++ b/dom/svg/SVGFESpecularLightingElement.cpp
@@ -74,29 +74,27 @@ SVGFESpecularLightingElement::GetPrimiti
                                                       const nsTArray<bool>& aInputsAreTainted,
                                                       nsTArray<RefPtr<SourceSurface>>& aInputImages)
 {
   float specularExponent = mNumberAttributes[SPECULAR_EXPONENT].GetAnimValue();
   float specularConstant = mNumberAttributes[SPECULAR_CONSTANT].GetAnimValue();
 
   // specification defined range (15.22)
   if (specularExponent < 1 || specularExponent > 128) {
-    return FilterPrimitiveDescription(PrimitiveType::Empty);
+    return FilterPrimitiveDescription();
   }
 
-  FilterPrimitiveDescription descr(PrimitiveType::SpecularLighting);
   SpecularLightingAttributes atts;
   atts.mLightingConstant = specularConstant;
   atts.mSpecularExponent = specularExponent;
   if (!AddLightingAttributes(static_cast<DiffuseLightingAttributes*>(&atts), aInstance)) {
-    return FilterPrimitiveDescription(PrimitiveType::Empty);
+    return FilterPrimitiveDescription();
   }
 
-  descr.Attributes() = AsVariant(std::move(atts));
-  return descr;
+  return FilterPrimitiveDescription(AsVariant(std::move(atts)));
 }
 
 bool
 SVGFESpecularLightingElement::AttributeAffectsRendering(int32_t aNameSpaceID,
                                                         nsAtom* aAttribute) const
 {
   return SVGFESpecularLightingElementBase::AttributeAffectsRendering(aNameSpaceID, aAttribute) ||
          (aNameSpaceID == kNameSpaceID_None &&
--- a/dom/svg/SVGFETileElement.cpp
+++ b/dom/svg/SVGFETileElement.cpp
@@ -49,17 +49,17 @@ SVGFETileElement::GetSourceImageNames(ns
 // nsSVGElement methods
 
 FilterPrimitiveDescription
 SVGFETileElement::GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
                                           const IntRect& aFilterSubregion,
                                           const nsTArray<bool>& aInputsAreTainted,
                                           nsTArray<RefPtr<SourceSurface>>& aInputImages)
 {
-  return FilterPrimitiveDescription(PrimitiveType::Tile);
+  return FilterPrimitiveDescription(AsVariant(TileAttributes()));
 }
 
 bool
 SVGFETileElement::AttributeAffectsRendering(int32_t aNameSpaceID,
                                             nsAtom* aAttribute) const
 {
   return SVGFETileElementBase::AttributeAffectsRendering(aNameSpaceID,
                                                          aAttribute) ||
--- a/dom/svg/SVGFETurbulenceElement.cpp
+++ b/dom/svg/SVGFETurbulenceElement.cpp
@@ -131,23 +131,21 @@ SVGFETurbulenceElement::GetPrimitiveDesc
   uint32_t octaves = clamped(mIntegerAttributes[OCTAVES].GetAnimValue(), 0, MAX_OCTAVES);
   uint32_t type = mEnumAttributes[TYPE].GetAnimValue();
   uint16_t stitch = mEnumAttributes[STITCHTILES].GetAnimValue();
 
   if (fX == 0 && fY == 0) {
     // A base frequency of zero results in transparent black for
     // type="turbulence" and in 50% alpha 50% gray for type="fractalNoise".
     if (type == SVG_TURBULENCE_TYPE_TURBULENCE) {
-      return FilterPrimitiveDescription(PrimitiveType::Empty);
+      return FilterPrimitiveDescription();
     }
-    FilterPrimitiveDescription descr(PrimitiveType::Flood);
     FloodAttributes atts;
     atts.mColor = Color(0.5, 0.5, 0.5, 0.5);
-    descr.Attributes() = AsVariant(std::move(atts));
-    return descr;
+    return FilterPrimitiveDescription(AsVariant(std::move(atts)));
   }
 
   // We interpret the base frequency as relative to user space units. In other
   // words, we consider one turbulence base period to be 1 / fX user space
   // units wide and 1 / fY user space units high. We do not scale the frequency
   // depending on the filter primitive region.
   // We now convert the frequency from user space to filter space.
   // If a frequency in user space units is zero, then it will also be zero in
@@ -157,26 +155,24 @@ SVGFETurbulenceElement::GetPrimitiveDesc
   gfxRect firstPeriodInUserSpace(0, 0,
                                  fX == 0 ? 1 : (1 / fX),
                                  fY == 0 ? 1 : (1 / fY));
   gfxRect firstPeriodInFilterSpace = aInstance->UserSpaceToFilterSpace(firstPeriodInUserSpace);
   Size frequencyInFilterSpace(fX == 0 ? 0 : (1 / firstPeriodInFilterSpace.width),
                               fY == 0 ? 0 : (1 / firstPeriodInFilterSpace.height));
   gfxPoint offset = firstPeriodInFilterSpace.TopLeft();
 
-  FilterPrimitiveDescription descr(PrimitiveType::Turbulence);
   TurbulenceAttributes atts;
   atts.mOffset = IntPoint::Truncate(offset.x, offset.y);
   atts.mBaseFrequency = frequencyInFilterSpace;
   atts.mSeed = seed;
   atts.mOctaves = octaves;
   atts.mStitchable = stitch == SVG_STITCHTYPE_STITCH;
   atts.mType = type;
-  descr.Attributes() = AsVariant(std::move(atts));
-  return descr;
+  return FilterPrimitiveDescription(AsVariant(std::move(atts)));
 }
 
 bool
 SVGFETurbulenceElement::AttributeAffectsRendering(int32_t aNameSpaceID,
                                                     nsAtom* aAttribute) const
 {
   return SVGFETurbulenceElementBase::AttributeAffectsRendering(aNameSpaceID, aAttribute) ||
          (aNameSpaceID == kNameSpaceID_None &&
--- a/gfx/ipc/GfxMessageUtils.h
+++ b/gfx/ipc/GfxMessageUtils.h
@@ -249,24 +249,16 @@ template <>
 struct ParamTraits<mozilla::gfx::FeatureStatus>
   : public ContiguousEnumSerializer<
              mozilla::gfx::FeatureStatus,
              mozilla::gfx::FeatureStatus::Unused,
              mozilla::gfx::FeatureStatus::LAST>
 {};
 
 template <>
-struct ParamTraits<mozilla::gfx::PrimitiveType>
-  : public ContiguousEnumSerializer<
-             mozilla::gfx::PrimitiveType,
-             mozilla::gfx::PrimitiveType::Empty,
-             mozilla::gfx::PrimitiveType::Max>
-{};
-
-template <>
 struct ParamTraits<mozilla::gfx::LightType>
   : public ContiguousEnumSerializer<
              mozilla::gfx::LightType,
              mozilla::gfx::LightType::None,
              mozilla::gfx::LightType::Max>
 {};
 
 template <>
@@ -1176,47 +1168,43 @@ struct ParamTraits<mozilla::gfx::Composi
 
 template <>
 struct ParamTraits<mozilla::gfx::FilterPrimitiveDescription>
 {
   typedef mozilla::gfx::FilterPrimitiveDescription paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
-    WriteParam(aMsg, aParam.Type());
     WriteParam(aMsg, aParam.PrimitiveSubregion());
     WriteParam(aMsg, aParam.FilterSpaceBounds());
     WriteParam(aMsg, aParam.IsTainted());
     WriteParam(aMsg, aParam.OutputColorSpace());
     WriteParam(aMsg, aParam.NumberOfInputs());
     for (size_t i = 0; i < aParam.NumberOfInputs(); i++) {
       WriteParam(aMsg, aParam.InputPrimitiveIndex(i));
       WriteParam(aMsg, aParam.InputColorSpace(i));
     }
     WriteParam(aMsg, aParam.Attributes());
   }
 
   static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
-    mozilla::gfx::PrimitiveType type;
     mozilla::gfx::IntRect primitiveSubregion;
     mozilla::gfx::IntRect filterSpaceBounds;
     bool isTainted = false;
     mozilla::gfx::ColorSpace outputColorSpace;
     size_t numberOfInputs = 0;
-    if (!ReadParam(aMsg, aIter, &type) ||
-        !ReadParam(aMsg, aIter, &primitiveSubregion) ||
+    if (!ReadParam(aMsg, aIter, &primitiveSubregion) ||
         !ReadParam(aMsg, aIter, &filterSpaceBounds) ||
         !ReadParam(aMsg, aIter, &isTainted) ||
         !ReadParam(aMsg, aIter, &outputColorSpace) ||
         !ReadParam(aMsg, aIter, &numberOfInputs)) {
       return false;
     }
 
-    aResult->SetType(type);
     aResult->SetPrimitiveSubregion(primitiveSubregion);
     aResult->SetFilterSpaceBounds(filterSpaceBounds);
     aResult->SetIsTainted(isTainted);
     aResult->SetOutputColorSpace(outputColorSpace);
 
     for (size_t i = 0; i < numberOfInputs; i++) {
       int32_t inputPrimitiveIndex = 0;
       mozilla::gfx::ColorSpace inputColorSpace;
--- a/gfx/src/FilterSupport.cpp
+++ b/gfx/src/FilterSupport.cpp
@@ -1086,17 +1086,17 @@ FilterNodeFromPrimitiveDescription(const
     already_AddRefed<FilterNode> match(const SpecularLightingAttributes& aLighting)
     {
       return match(*(static_cast<const DiffuseLightingAttributes*>(&aLighting)));
     }
 
     already_AddRefed<FilterNode> match(const DiffuseLightingAttributes& aLighting)
     {
       bool isSpecular =
-        mDescription.Type() == PrimitiveType::SpecularLighting;
+        mDescription.Attributes().is<SpecularLightingAttributes>();
 
       if (aLighting.mLightType == LightType::None) {
         return nullptr;
       }
 
       enum { POINT = 0, SPOT, DISTANT } lightType = POINT;
 
       switch (aLighting.mLightType) {
@@ -1225,38 +1225,35 @@ ElementForIndex(int32_t aIndex,
   }
 }
 
 static AlphaModel
 InputAlphaModelForPrimitive(const FilterPrimitiveDescription& aDescr,
                             int32_t aInputIndex,
                             AlphaModel aOriginalAlphaModel)
 {
-  switch (aDescr.Type()) {
-    case PrimitiveType::Tile:
-    case PrimitiveType::Offset:
-    case PrimitiveType::ToAlpha:
+  const PrimitiveAttributes& atts = aDescr.Attributes();
+  if (atts.is<TileAttributes>() ||
+      atts.is<OffsetAttributes>() ||
+      atts.is<ToAlphaAttributes>()) {
       return aOriginalAlphaModel;
-
-    case PrimitiveType::ColorMatrix:
-    case PrimitiveType::ComponentTransfer:
-      return AlphaModel::Unpremultiplied;
-
-    case PrimitiveType::DisplacementMap:
-      return aInputIndex == 0 ?
-        AlphaModel::Premultiplied : AlphaModel::Unpremultiplied;
-
-    case PrimitiveType::ConvolveMatrix:
-      MOZ_ASSERT(aDescr.Attributes().is<ConvolveMatrixAttributes>());
-      return aDescr.Attributes().as<ConvolveMatrixAttributes>().mPreserveAlpha ?
-        AlphaModel::Unpremultiplied : AlphaModel::Premultiplied;
-
-    default:
-      return AlphaModel::Premultiplied;
+  }
+  if (atts.is<ColorMatrixAttributes>() ||
+      atts.is<ComponentTransferAttributes>()) {
+    return AlphaModel::Unpremultiplied;
   }
+  if (atts.is<DisplacementMapAttributes>()) {
+    return aInputIndex == 0 ?
+      AlphaModel::Premultiplied : AlphaModel::Unpremultiplied;
+  }
+  if (atts.is<ConvolveMatrixAttributes>()) {
+    return atts.as<ConvolveMatrixAttributes>().mPreserveAlpha ?
+      AlphaModel::Unpremultiplied : AlphaModel::Premultiplied;
+  }
+  return AlphaModel::Premultiplied;
 }
 
 static AlphaModel
 OutputAlphaModelForPrimitive(const FilterPrimitiveDescription& aDescr,
                              const nsTArray<AlphaModel>& aInputAlphaModels)
 {
   if (aInputAlphaModels.Length()) {
     // For filters with inputs, the output is premultiplied if and only if the
@@ -2035,92 +2032,85 @@ FilterSupport::ComputeSourceNeededRegion
   const FilterPrimitiveDescription& firstDescr = primitives[0];
   aSourceGraphicNeededRegion.And(aSourceGraphicNeededRegion,
                                  firstDescr.FilterSpaceBounds());
 }
 
 // FilterPrimitiveDescription
 
 FilterPrimitiveDescription::FilterPrimitiveDescription()
- : mType(PrimitiveType::Empty)
- , mAttributes(EmptyAttributes())
+ : mAttributes(EmptyAttributes())
  , mOutputColorSpace(ColorSpace::SRGB)
  , mIsTainted(false)
 {
 }
 
-FilterPrimitiveDescription::FilterPrimitiveDescription(PrimitiveType aType)
- : mType(aType)
- , mAttributes(EmptyAttributes())
+FilterPrimitiveDescription::FilterPrimitiveDescription(PrimitiveAttributes&& aAttributes)
+ : mAttributes(std::move(aAttributes))
  , mOutputColorSpace(ColorSpace::SRGB)
  , mIsTainted(false)
 {
 }
 
 FilterPrimitiveDescription::FilterPrimitiveDescription(const FilterPrimitiveDescription& aOther)
- : mType(aOther.mType)
- , mAttributes(aOther.mAttributes)
+ : mAttributes(aOther.mAttributes)
  , mInputPrimitives(aOther.mInputPrimitives)
  , mFilterPrimitiveSubregion(aOther.mFilterPrimitiveSubregion)
  , mFilterSpaceBounds(aOther.mFilterSpaceBounds)
  , mInputColorSpaces(aOther.mInputColorSpaces)
  , mOutputColorSpace(aOther.mOutputColorSpace)
  , mIsTainted(aOther.mIsTainted)
 {
 }
 
 FilterPrimitiveDescription&
 FilterPrimitiveDescription::operator=(const FilterPrimitiveDescription& aOther)
 {
   if (this != &aOther) {
-    mType = aOther.mType;
     mAttributes = aOther.mAttributes;
     mInputPrimitives = aOther.mInputPrimitives;
     mFilterPrimitiveSubregion = aOther.mFilterPrimitiveSubregion;
     mFilterSpaceBounds = aOther.mFilterSpaceBounds;
     mInputColorSpaces = aOther.mInputColorSpaces;
     mOutputColorSpace = aOther.mOutputColorSpace;
     mIsTainted = aOther.mIsTainted;
   }
   return *this;
 }
 
 FilterPrimitiveDescription::FilterPrimitiveDescription(FilterPrimitiveDescription&& aOther)
- : mType(aOther.mType)
- , mAttributes(std::move(aOther.mAttributes))
+ : mAttributes(std::move(aOther.mAttributes))
  , mInputPrimitives(std::move(aOther.mInputPrimitives))
  , mFilterPrimitiveSubregion(aOther.mFilterPrimitiveSubregion)
  , mFilterSpaceBounds(aOther.mFilterSpaceBounds)
  , mInputColorSpaces(std::move(aOther.mInputColorSpaces))
  , mOutputColorSpace(aOther.mOutputColorSpace)
  , mIsTainted(aOther.mIsTainted)
 {
 }
 
 FilterPrimitiveDescription&
 FilterPrimitiveDescription::operator=(FilterPrimitiveDescription&& aOther)
 {
   if (this != &aOther) {
-    mType = aOther.mType;
     mAttributes = std::move(aOther.mAttributes);
     mInputPrimitives = std::move(aOther.mInputPrimitives);
     mFilterPrimitiveSubregion = aOther.mFilterPrimitiveSubregion;
     mFilterSpaceBounds = aOther.mFilterSpaceBounds;
     mInputColorSpaces = std::move(aOther.mInputColorSpaces);
     mOutputColorSpace = aOther.mOutputColorSpace;
     mIsTainted = aOther.mIsTainted;
   }
   return *this;
 }
 
 bool
 FilterPrimitiveDescription::operator==(const FilterPrimitiveDescription& aOther) const
 {
-  return mType == aOther.mType &&
-    mFilterPrimitiveSubregion.IsEqualInterior(aOther.mFilterPrimitiveSubregion) &&
+  return mFilterPrimitiveSubregion.IsEqualInterior(aOther.mFilterPrimitiveSubregion) &&
     mFilterSpaceBounds.IsEqualInterior(aOther.mFilterSpaceBounds) &&
     mOutputColorSpace == aOther.mOutputColorSpace &&
     mIsTainted == aOther.mIsTainted &&
     mInputPrimitives == aOther.mInputPrimitives &&
     mInputColorSpaces == aOther.mInputColorSpaces &&
     mAttributes == aOther.mAttributes;
 }
 
--- a/gfx/src/FilterSupport.h
+++ b/gfx/src/FilterSupport.h
@@ -89,40 +89,16 @@ const unsigned short SVG_FECOMPOSITE_OPE
 
 class DrawTarget;
 class SourceSurface;
 struct FilterAttribute;
 
 // Limits
 const float kMaxStdDeviation = 500;
 
-enum class PrimitiveType {
-  Empty = 0,
-  Blend,
-  Morphology,
-  ColorMatrix,
-  Flood,
-  Tile,
-  ComponentTransfer,
-  Opacity,
-  ConvolveMatrix,
-  Offset,
-  DisplacementMap,
-  Turbulence,
-  Composite,
-  Merge,
-  Image,
-  GaussianBlur,
-  DropShadow,
-  DiffuseLighting,
-  SpecularLighting,
-  ToAlpha,
-  Max
-};
-
 // Simple PrimitiveAttributes:
 
 struct EmptyAttributes {
   bool operator==(const EmptyAttributes& aOther) const {
     return true;
   }
 };
 
@@ -463,24 +439,22 @@ public:
   enum {
     kPrimitiveIndexSourceGraphic = -1,
     kPrimitiveIndexSourceAlpha = -2,
     kPrimitiveIndexFillPaint = -3,
     kPrimitiveIndexStrokePaint = -4
   };
 
   FilterPrimitiveDescription();
-  explicit FilterPrimitiveDescription(PrimitiveType aType);
+  explicit FilterPrimitiveDescription(PrimitiveAttributes&& aAttributes);
   FilterPrimitiveDescription(FilterPrimitiveDescription&& aOther);
   FilterPrimitiveDescription& operator=(FilterPrimitiveDescription&& aOther);
   FilterPrimitiveDescription(const FilterPrimitiveDescription& aOther);
   FilterPrimitiveDescription& operator=(const FilterPrimitiveDescription& aOther);
 
-  PrimitiveType Type() const { return mType; }
-  void SetType(PrimitiveType aType) { mType = aType; }
   const PrimitiveAttributes& Attributes() const { return mAttributes; }
   PrimitiveAttributes& Attributes() { return mAttributes; }
 
   IntRect PrimitiveSubregion() const { return mFilterPrimitiveSubregion; }
   IntRect FilterSpaceBounds() const { return mFilterSpaceBounds; }
   bool IsTainted() const { return mIsTainted; }
 
   size_t NumberOfInputs() const { return mInputPrimitives.Length(); }
@@ -532,17 +506,16 @@ public:
 
   bool operator==(const FilterPrimitiveDescription& aOther) const;
   bool operator!=(const FilterPrimitiveDescription& aOther) const
   {
     return !(*this == aOther);
   }
 
 private:
-  PrimitiveType mType;
   PrimitiveAttributes mAttributes;
   nsTArray<int32_t> mInputPrimitives;
   IntRect mFilterPrimitiveSubregion;
   IntRect mFilterSpaceBounds;
   nsTArray<ColorSpace> mInputColorSpaces;
   ColorSpace mOutputColorSpace;
   bool mIsTainted;
 };
--- a/layout/svg/nsCSSFilterInstance.cpp
+++ b/layout/svg/nsCSSFilterInstance.cpp
@@ -39,78 +39,48 @@ nsCSSFilterInstance::nsCSSFilterInstance
   , mFrameSpaceInCSSPxToFilterSpaceTransform(aFrameSpaceInCSSPxToFilterSpaceTransform)
 {
 }
 
 nsresult
 nsCSSFilterInstance::BuildPrimitives(nsTArray<FilterPrimitiveDescription>& aPrimitiveDescrs,
                                      bool aInputIsTainted)
 {
-  FilterPrimitiveDescription descr;
+  FilterPrimitiveDescription descr = CreatePrimitiveDescription(aPrimitiveDescrs,
+                                                                aInputIsTainted);
   nsresult result;
-
   switch(mFilter.GetType()) {
     case NS_STYLE_FILTER_BLUR:
-      descr = CreatePrimitiveDescription(PrimitiveType::GaussianBlur,
-                                         aPrimitiveDescrs,
-                                         aInputIsTainted);
       result = SetAttributesForBlur(descr);
       break;
     case NS_STYLE_FILTER_BRIGHTNESS:
-      descr = CreatePrimitiveDescription(PrimitiveType::ComponentTransfer,
-                                         aPrimitiveDescrs,
-                                         aInputIsTainted);
       result = SetAttributesForBrightness(descr);
       break;
     case NS_STYLE_FILTER_CONTRAST:
-      descr = CreatePrimitiveDescription(PrimitiveType::ComponentTransfer,
-                                         aPrimitiveDescrs,
-                                         aInputIsTainted);
       result = SetAttributesForContrast(descr);
       break;
     case NS_STYLE_FILTER_DROP_SHADOW:
-      descr = CreatePrimitiveDescription(PrimitiveType::DropShadow,
-                                         aPrimitiveDescrs,
-                                         aInputIsTainted);
       result = SetAttributesForDropShadow(descr);
       break;
     case NS_STYLE_FILTER_GRAYSCALE:
-      descr = CreatePrimitiveDescription(PrimitiveType::ColorMatrix,
-                                         aPrimitiveDescrs,
-                                         aInputIsTainted);
       result = SetAttributesForGrayscale(descr);
       break;
     case NS_STYLE_FILTER_HUE_ROTATE:
-      descr = CreatePrimitiveDescription(PrimitiveType::ColorMatrix,
-                                         aPrimitiveDescrs,
-                                         aInputIsTainted);
       result = SetAttributesForHueRotate(descr);
       break;
     case NS_STYLE_FILTER_INVERT:
-      descr = CreatePrimitiveDescription(PrimitiveType::ComponentTransfer,
-                                         aPrimitiveDescrs,
-                                         aInputIsTainted);
       result = SetAttributesForInvert(descr);
       break;
     case NS_STYLE_FILTER_OPACITY:
-      descr = CreatePrimitiveDescription(PrimitiveType::Opacity,
-                                         aPrimitiveDescrs,
-                                         aInputIsTainted);
       result = SetAttributesForOpacity(descr);
       break;
     case NS_STYLE_FILTER_SATURATE:
-      descr = CreatePrimitiveDescription(PrimitiveType::ColorMatrix,
-                                         aPrimitiveDescrs,
-                                         aInputIsTainted);
       result = SetAttributesForSaturate(descr);
       break;
     case NS_STYLE_FILTER_SEPIA:
-      descr = CreatePrimitiveDescription(PrimitiveType::ColorMatrix,
-                                         aPrimitiveDescrs,
-                                         aInputIsTainted);
       result = SetAttributesForSepia(descr);
       break;
     default:
       MOZ_ASSERT_UNREACHABLE("not a valid CSS filter type");
       return NS_ERROR_FAILURE;
   }
 
   if (NS_FAILED(result)) {
@@ -122,20 +92,19 @@ nsCSSFilterInstance::BuildPrimitives(nsT
   SetBounds(descr, aPrimitiveDescrs);
 
   // Add this primitive to the filter chain.
   aPrimitiveDescrs.AppendElement(std::move(descr));
   return NS_OK;
 }
 
 FilterPrimitiveDescription
-nsCSSFilterInstance::CreatePrimitiveDescription(PrimitiveType aType,
-                                                const nsTArray<FilterPrimitiveDescription>& aPrimitiveDescrs,
+nsCSSFilterInstance::CreatePrimitiveDescription(const nsTArray<FilterPrimitiveDescription>& aPrimitiveDescrs,
                                                 bool aInputIsTainted) {
-  FilterPrimitiveDescription descr(aType);
+  FilterPrimitiveDescription descr;
   int32_t inputIndex = GetLastResultIndex(aPrimitiveDescrs);
   descr.SetInputPrimitive(0, inputIndex);
   descr.SetIsTainted(inputIndex < 0 ? aInputIsTainted : aPrimitiveDescrs[inputIndex].IsTainted());
   descr.SetInputColorSpace(0, ColorSpace::SRGB);
   descr.SetOutputColorSpace(ColorSpace::SRGB);
   return descr;
 }
 
--- a/layout/svg/nsCSSFilterInstance.h
+++ b/layout/svg/nsCSSFilterInstance.h
@@ -22,17 +22,16 @@ struct nsStyleFilter;
  * filter function (e.g. blur(3px)) from the style system into a
  * FilterPrimitiveDescription connected to the filter graph.
  */
 class nsCSSFilterInstance
 {
   typedef mozilla::gfx::Color Color;
   typedef mozilla::gfx::FilterPrimitiveDescription FilterPrimitiveDescription;
   typedef mozilla::gfx::IntPoint IntPoint;
-  typedef mozilla::gfx::PrimitiveType PrimitiveType;
   typedef mozilla::gfx::Size Size;
 
 public:
   /**
    * @param aFilter The CSS filter from the style system. This class stores
    *   aFilter by reference, so callers should avoid modifying or deleting
    *   aFilter during the lifetime of nsCSSFilterInstance.
    * @param aShadowFallbackColor The color that should be used for
@@ -62,18 +61,17 @@ public:
   nsresult BuildPrimitives(nsTArray<FilterPrimitiveDescription>& aPrimitiveDescrs,
                            bool aInputIsTainted);
 
 private:
   /**
    * Returns a new FilterPrimitiveDescription with its basic properties set up.
    * See the comment above BuildPrimitives for the meaning of aInputIsTainted.
    */
-  FilterPrimitiveDescription CreatePrimitiveDescription(PrimitiveType aType,
-                                                        const nsTArray<FilterPrimitiveDescription>& aPrimitiveDescrs,
+  FilterPrimitiveDescription CreatePrimitiveDescription(const nsTArray<FilterPrimitiveDescription>& aPrimitiveDescrs,
                                                         bool aInputIsTainted);
 
   /**
    * Sets aDescr's attributes using the style info in mFilter.
    */
   nsresult SetAttributesForBlur(FilterPrimitiveDescription& aDescr);
   nsresult SetAttributesForBrightness(FilterPrimitiveDescription& aDescr);
   nsresult SetAttributesForContrast(FilterPrimitiveDescription& aDescr);
--- a/layout/svg/nsSVGFilterInstance.cpp
+++ b/layout/svg/nsSVGFilterInstance.cpp
@@ -304,29 +304,29 @@ nsSVGFilterInstance::GetOrCreateSourceAl
   if (mSourceGraphicIndex < 0) {
     mSourceAlphaIndex = FilterPrimitiveDescription::kPrimitiveIndexSourceAlpha;
     mSourceAlphaAvailable = true;
     return mSourceAlphaIndex;
   }
 
   // Otherwise, create a primitive description to turn the previous filter's
   // output into a SourceAlpha input.
-  FilterPrimitiveDescription descr(PrimitiveType::ToAlpha);
+  FilterPrimitiveDescription descr(AsVariant(ToAlphaAttributes()));
   descr.SetInputPrimitive(0, mSourceGraphicIndex);
 
   const FilterPrimitiveDescription& sourcePrimitiveDescr =
     aPrimitiveDescrs[mSourceGraphicIndex];
   descr.SetPrimitiveSubregion(sourcePrimitiveDescr.PrimitiveSubregion());
   descr.SetIsTainted(sourcePrimitiveDescr.IsTainted());
 
   ColorSpace colorSpace = sourcePrimitiveDescr.OutputColorSpace();
   descr.SetInputColorSpace(0, colorSpace);
   descr.SetOutputColorSpace(colorSpace);
 
-  aPrimitiveDescrs.AppendElement(descr);
+  aPrimitiveDescrs.AppendElement(std::move(descr));
   mSourceAlphaIndex = aPrimitiveDescrs.Length() - 1;
   mSourceAlphaAvailable = true;
   return mSourceAlphaIndex;
 }
 
 nsresult
 nsSVGFilterInstance::GetSourceIndices(nsSVGFE* aPrimitiveElement,
                                       nsTArray<FilterPrimitiveDescription>& aPrimitiveDescrs,