Bug 615658 - SMIL animation of some filter attributes don't invalidate correctly. r=jwatt, a=roc.
authorRobert Longson <longsonr@gmail.com>
Sun, 05 Dec 2010 11:37:45 +0000
changeset 58625 f227a6e64b3f60ce5af4583e7e1fcf3c00cafa84
parent 58624 30b83f45346c6ae6f59cebaddae1a929b2bf2e99
child 58626 d1a5599b49fa787534a3a2c568ff35cf502f7a93
push id17386
push userjwatt@jwatt.org
push dateSun, 05 Dec 2010 12:47:56 +0000
treeherdermozilla-central@f227a6e64b3f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjwatt, roc
bugs615658
milestone2.0b8pre
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 615658 - SMIL animation of some filter attributes don't invalidate correctly. r=jwatt, a=roc.
content/svg/content/src/nsSVGFilters.cpp
layout/base/nsCSSFrameConstructor.cpp
layout/reftests/svg/smil/reftest.list
--- a/content/svg/content/src/nsSVGFilters.cpp
+++ b/content/svg/content/src/nsSVGFilters.cpp
@@ -75,16 +75,17 @@
 #ifndef WINCE
 #undef LoadImage
 #endif
 #endif
 
 #define NUM_ENTRIES_IN_4x5_MATRIX 20
 
 using namespace mozilla;
+using namespace mozilla::dom;
 
 static void
 CopyDataRect(PRUint8 *aDest, const PRUint8 *aSrc, PRUint32 aStride,
              const nsIntRect& aDataRect)
 {
   for (PRInt32 y = aDataRect.y; y < aDataRect.YMost(); y++) {
     memcpy(aDest + y * aStride + 4 * aDataRect.x,
            aSrc + y * aStride + 4 * aDataRect.x,
@@ -301,17 +302,17 @@ NS_IMETHODIMP nsSVGFE::GetResult(nsIDOMS
 
 nsSVGElement::LengthAttributesInfo
 nsSVGFE::GetLengthInfo()
 {
   return LengthAttributesInfo(mLengthAttributes, sLengthInfo,
                               NS_ARRAY_LENGTH(sLengthInfo));
 }
 
-inline static void DidAnimateAttr(nsSVGFE *aFilterPrimitive)
+inline static void DidAnimateAttr(Element *aFilterPrimitive)
 {
   // nsSVGLeafFrame doesn't implement AttributeChanged.
   nsIFrame* frame = aFilterPrimitive->GetPrimaryFrame();
   if (frame) {
     nsSVGEffects::InvalidateRenderingObservers(frame);
   }
 }
 
@@ -1774,20 +1775,33 @@ public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMSVGCOMPONENTTRANSFERFUNCTIONELEMENT
 
   virtual PRInt32 GetChannel() = 0;
   void GenerateLookupTable(PRUint8* aTable);
 
 protected:
   virtual NumberAttributesInfo GetNumberInfo();
+  virtual void DidAnimateNumber(PRUint8 aAttrEnum) {
+    // No frame, use parent's
+    NS_ASSERTION(!GetPrimaryFrame(), "Not expecting a frame");
+    DidAnimateAttr(nsSVGUtils::GetParentElement(this));
+  }
   virtual EnumAttributesInfo GetEnumInfo();
+  virtual void DidAnimateEnum(PRUint8 aAttrEnum) {
+    // No frame, use parent's
+    NS_ASSERTION(!GetPrimaryFrame(), "Not expecting a frame");
+    DidAnimateAttr(nsSVGUtils::GetParentElement(this));
+  }
   virtual NumberListAttributesInfo GetNumberListInfo();
-
-  virtual void DidAnimateNumberList(PRUint8 aAttrEnum);
+  virtual void DidAnimateNumberList(PRUint8 aAttrEnum) {
+    // No frame, use parent's
+    NS_ASSERTION(!GetPrimaryFrame(), "Not expecting a frame");
+    DidAnimateAttr(nsSVGUtils::GetParentElement(this));
+  }
 
   // nsIDOMSVGComponentTransferFunctionElement properties:
   enum { TABLEVALUES };
   SVGAnimatedNumberList mNumberListAttributes[1];
   static NumberListInfo sNumberListInfo[1];
 
   enum { SLOPE, INTERCEPT, AMPLITUDE, EXPONENT, OFFSET };
   nsSVGNumber2 mNumberAttributes[5];
@@ -2048,32 +2062,16 @@ nsSVGComponentTransferFunctionElement::G
 
 nsSVGElement::NumberAttributesInfo
 nsSVGComponentTransferFunctionElement::GetNumberInfo()
 {
   return NumberAttributesInfo(mNumberAttributes, sNumberInfo,
                               NS_ARRAY_LENGTH(sNumberInfo));
 }
 
-void
-nsSVGComponentTransferFunctionElement::DidAnimateNumberList(PRUint8 aAttrEnum)
-{
-  // We don't have a frame, so use our parent's
-  nsCOMPtr<nsIDOMSVGFEComponentTransferElement> compTrans =
-    do_QueryInterface(GetParent());
-  if (compTrans) {
-    // nsSVGLeafFrame doesn't implement AttributeChanged.
-    nsIFrame* frame = static_cast<nsSVGFE*>(GetParent())->GetPrimaryFrame();
-    if (frame) {
-      nsSVGEffects::InvalidateRenderingObservers(frame);
-    }
-  }
-}
-
-
 class nsSVGFEFuncRElement : public nsSVGComponentTransferFunctionElement,
                             public nsIDOMSVGFEFuncRElement
 {
   friend nsresult NS_NewSVGFEFuncRElement(nsIContent **aResult,
                                           already_AddRefed<nsINodeInfo> aNodeInfo);
 protected:
   nsSVGFEFuncRElement(already_AddRefed<nsINodeInfo> aNodeInfo) 
     : nsSVGComponentTransferFunctionElement(aNodeInfo) {}
@@ -4330,16 +4328,21 @@ public:
   NS_FORWARD_NSIDOMNODE(nsSVGFEDistantLightElementBase::)
   NS_FORWARD_NSIDOMELEMENT(nsSVGFEDistantLightElementBase::)
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   virtual nsXPCClassInfo* GetClassInfo();
 protected:
   virtual NumberAttributesInfo GetNumberInfo();
+  virtual void DidAnimateNumber(PRUint8 aAttrEnum) {
+    // No frame, use parent's
+    NS_ASSERTION(!GetPrimaryFrame(), "Not expecting a frame");
+    DidAnimateAttr(nsSVGUtils::GetParentElement(this));
+  }
 
   enum { AZIMUTH, ELEVATION };
   nsSVGNumber2 mNumberAttributes[2];
   static NumberInfo sNumberInfo[2];
 };
 
 NS_IMPL_NS_NEW_SVG_ELEMENT(FEDistantLight)
 
@@ -4418,16 +4421,21 @@ public:
   NS_FORWARD_NSIDOMNODE(nsSVGFEPointLightElementBase::)
   NS_FORWARD_NSIDOMELEMENT(nsSVGFEPointLightElementBase::)
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   virtual nsXPCClassInfo* GetClassInfo();
 protected:
   virtual NumberAttributesInfo GetNumberInfo();
+  virtual void DidAnimateNumber(PRUint8 aAttrEnum) {
+    // No frame, use parent's
+    NS_ASSERTION(!GetPrimaryFrame(), "Not expecting a frame");
+    DidAnimateAttr(nsSVGUtils::GetParentElement(this));
+  }
 
   enum { X, Y, Z };
   nsSVGNumber2 mNumberAttributes[3];
   static NumberInfo sNumberInfo[3];
 };
 
 NS_IMPL_NS_NEW_SVG_ELEMENT(FEPointLight)
 
@@ -4511,16 +4519,21 @@ public:
   NS_FORWARD_NSIDOMNODE(nsSVGFESpotLightElementBase::)
   NS_FORWARD_NSIDOMELEMENT(nsSVGFESpotLightElementBase::)
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   virtual nsXPCClassInfo* GetClassInfo();
 protected:
   virtual NumberAttributesInfo GetNumberInfo();
+  virtual void DidAnimateNumber(PRUint8 aAttrEnum) {
+    // No frame, use parent's
+    NS_ASSERTION(!GetPrimaryFrame(), "Not expecting a frame");
+    DidAnimateAttr(nsSVGUtils::GetParentElement(this));
+  }
 
   enum { X, Y, Z, POINTS_AT_X, POINTS_AT_Y, POINTS_AT_Z,
          SPECULAR_EXPONENT, LIMITING_CONE_ANGLE };
   nsSVGNumber2 mNumberAttributes[8];
   static NumberInfo sNumberInfo[8];
 };
 
 NS_IMPL_NS_NEW_SVG_ELEMENT(FESpotLight)
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -4774,28 +4774,35 @@ nsCSSFrameConstructor::FindSVGData(nsICo
     // content within svg:foreignObject at all (SVG 1.1, section
     // 23.2), but if it does, it better be svg:svg.  So given that
     // we're allowing it, treat it as a non-SVG parent.
     parentIsSVG = parentNSID == kNameSpaceID_SVG &&
                   parentTag != nsGkAtoms::foreignObject;
   }
 
   if ((aTag != nsGkAtoms::svg && !parentIsSVG) ||
-      (aTag == nsGkAtoms::desc || aTag == nsGkAtoms::title)) {
+      (aTag == nsGkAtoms::desc || aTag == nsGkAtoms::title ||
+       aTag == nsGkAtoms::feFuncR || aTag == nsGkAtoms::feFuncG ||
+       aTag == nsGkAtoms::feFuncB || aTag == nsGkAtoms::feFuncA ||
+       aTag == nsGkAtoms::feDistantLight || aTag == nsGkAtoms::fePointLight ||
+       aTag == nsGkAtoms::feSpotLight)) {
     // Sections 5.1 and G.4 of SVG 1.1 say that SVG elements other than
     // svg:svg not contained within svg:svg are incorrect, although they
     // don't seem to specify error handling.  Ignore them, since many of
     // our frame classes can't deal.  It *may* be that the document
     // should at that point be considered in error according to F.2, but
     // it's hard to tell.
     //
     // Style mutation can't change this situation, so don't bother
     // adding to the undisplayed content map.
     //
     // We don't currently handle any UI for desc/title
+    //
+    // The filter types are children of filter elements that use their
+    // parent frames when necessary
     return &sSuppressData;
   }
 
   // We don't need frames for animation elements
   if (aContent->IsNodeOfType(nsINode::eANIMATION)) {
     return &sSuppressData;
   }
 
@@ -4875,25 +4882,18 @@ nsCSSFrameConstructor::FindSVGData(nsICo
     SIMPLE_SVG_CREATE(use, NS_NewSVGUseFrame),
     SIMPLE_SVG_CREATE(marker, NS_NewSVGMarkerFrame),
     SIMPLE_SVG_CREATE(image, NS_NewSVGImageFrame),
     SIMPLE_SVG_CREATE(clipPath, NS_NewSVGClipPathFrame),
     SIMPLE_SVG_CREATE(textPath, NS_NewSVGTextPathFrame),
     SIMPLE_SVG_CREATE(filter, NS_NewSVGFilterFrame),
     SIMPLE_SVG_CREATE(pattern, NS_NewSVGPatternFrame),
     SIMPLE_SVG_CREATE(mask, NS_NewSVGMaskFrame),
-    SIMPLE_SVG_CREATE(feDistantLight, NS_NewSVGLeafFrame),
-    SIMPLE_SVG_CREATE(fePointLight, NS_NewSVGLeafFrame),
-    SIMPLE_SVG_CREATE(feSpotLight, NS_NewSVGLeafFrame),
     SIMPLE_SVG_CREATE(feBlend, NS_NewSVGLeafFrame),
     SIMPLE_SVG_CREATE(feColorMatrix, NS_NewSVGLeafFrame),
-    SIMPLE_SVG_CREATE(feFuncR, NS_NewSVGLeafFrame),
-    SIMPLE_SVG_CREATE(feFuncG, NS_NewSVGLeafFrame),
-    SIMPLE_SVG_CREATE(feFuncB, NS_NewSVGLeafFrame),
-    SIMPLE_SVG_CREATE(feFuncA, NS_NewSVGLeafFrame),
     SIMPLE_SVG_CREATE(feComposite, NS_NewSVGLeafFrame),
     SIMPLE_SVG_CREATE(feComponentTransfer, NS_NewSVGLeafFrame),
     SIMPLE_SVG_CREATE(feConvolveMatrix, NS_NewSVGLeafFrame),
     SIMPLE_SVG_CREATE(feDiffuseLighting, NS_NewSVGLeafFrame),
     SIMPLE_SVG_CREATE(feDisplacementMap, NS_NewSVGLeafFrame),
     SIMPLE_SVG_CREATE(feFlood, NS_NewSVGLeafFrame),
     SIMPLE_SVG_CREATE(feGaussianBlur, NS_NewSVGLeafFrame),
     SIMPLE_SVG_CREATE(feImage, NS_NewSVGLeafFrame),
--- a/layout/reftests/svg/smil/reftest.list
+++ b/layout/reftests/svg/smil/reftest.list
@@ -78,17 +78,20 @@ fails == anim-fillcolor-1.svg      anim-
 == anim-height-interp-5.svg anim-height-interp-5-ref.svg
 == anim-height-interp-6.svg anim-height-interp-6-ref.svg
 
 # animate some <length> attributes:
 == anim-filter-primitive-size-01.svg lime.svg
 == anim-filter-size-01.svg lime.svg
 
 # animate some <number> attributes:
+== anim-feComponentTransfer-01.svg lime.svg
+== anim-feDistantLight-01.svg anim-feDistantLight-01-ref.svg
 == anim-feOffset-01.svg lime.svg
+== anim-feSpotLight-01.svg anim-feSpotLight-01-ref.svg
 == anim-offset-01.svg lime.svg
 == anim-pathLength-01.svg anim-pathLength-01-ref.svg
 
 # animate some <integer> attributes:
 == anim-feTurbulence-numOctaves-01.svg anim-feTurbulence-numOctaves-01-ref.svg
 
 # animate some <angle> attributes:
 == anim-marker-orient-01.svg lime.svg