Bug 758505, Part 3: Avoid unnecessary invalidations on repeated calls to set the same animated value (for SMIL animations of CSS, mapped attrs, and motion). r=dholbert
authorRobert Longson <longsonr@gmail.com>
Fri, 01 Jun 2012 16:53:57 -0700
changeset 95613 123be65017577f98542852fc557efa66581100f7
parent 95612 0865e37d8cad23da3563664ebfaca458b11ea95b
child 95614 2f9736a307557c7d18c2c443a27a7ee4d5a9befe
push id825
push userdcamp@campd.org
push dateSat, 02 Jun 2012 23:58:00 +0000
treeherderfx-team@d0ebcaa7efb5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert
bugs758505
milestone15.0a1
Bug 758505, Part 3: Avoid unnecessary invalidations on repeated calls to set the same animated value (for SMIL animations of CSS, mapped attrs, and motion). r=dholbert
content/smil/nsSMILCSSProperty.cpp
content/smil/nsSMILMappedAttribute.cpp
content/svg/content/src/nsSVGGraphicElement.cpp
gfx/thebes/gfxMatrix.h
--- a/content/smil/nsSMILCSSProperty.cpp
+++ b/content/smil/nsSMILCSSProperty.cpp
@@ -161,16 +161,21 @@ nsSMILCSSProperty::SetAnimValue(const ns
     NS_WARNING("Failed to convert nsSMILValue for CSS property into a string");
     return NS_ERROR_FAILURE;
   }
 
   // Use string value to style the target element
   nsCOMPtr<nsICSSDeclaration> overrideDecl =
     do_QueryInterface(mElement->GetSMILOverrideStyle());
   if (overrideDecl) {
+    nsAutoString oldValStr;
+    overrideDecl->GetPropertyValue(mPropID, oldValStr);
+    if (valStr.Equals(oldValStr)) {
+      return NS_OK;
+    }
     overrideDecl->SetPropertyValue(mPropID, valStr);
   }
   return NS_OK;
 }
 
 void
 nsSMILCSSProperty::ClearAnimValue()
 {
--- a/content/smil/nsSMILMappedAttribute.cpp
+++ b/content/smil/nsSMILMappedAttribute.cpp
@@ -1,15 +1,16 @@
 /* -*- 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/. */
 
 /* representation of a SMIL-animatable mapped attribute on an element */
 #include "nsSMILMappedAttribute.h"
+#include "nsAttrValue.h"
 #include "nsPropertyTable.h"
 #include "nsContentErrors.h" // For NS_PROPTABLE_PROP_OVERWRITTEN
 #include "nsSMILValue.h"
 #include "nsSMILCSSValueType.h"
 #include "nsIContent.h"
 #include "nsIDocument.h"
 #include "nsIPresShell.h"
 #include "nsCSSProps.h"
@@ -87,20 +88,26 @@ nsSMILMappedAttribute::SetAnimValue(cons
 
   // Convert nsSMILValue to string
   nsAutoString valStr;
   if (!nsSMILCSSValueType::ValueToString(aValue, valStr)) {
     NS_WARNING("Failed to convert nsSMILValue for mapped attr into a string");
     return NS_ERROR_FAILURE;
   }
 
+  nsRefPtr<nsIAtom> attrName = GetAttrNameAtom();
+  nsStringBuffer* oldValStrBuf = static_cast<nsStringBuffer*>
+    (mElement->GetProperty(SMIL_MAPPED_ATTR_ANIMVAL, attrName));
+  if (oldValStrBuf && valStr.Equals(nsCheapString(oldValStrBuf))) {
+    return NS_OK;
+  }
+
   // Set the string as this mapped attribute's animated value.
   nsStringBuffer* valStrBuf =
     nsCSSValue::BufferFromString(nsString(valStr)).get();
-  nsRefPtr<nsIAtom> attrName = GetAttrNameAtom();
   nsresult rv = mElement->SetProperty(SMIL_MAPPED_ATTR_ANIMVAL,
                                       attrName, valStrBuf,
                                       ReleaseStringBufferPropertyValue);
   if (rv == NS_PROPTABLE_PROP_OVERWRITTEN) {
     rv = NS_OK;
   }
   FlushChangesToTargetAttr();
 
--- a/content/svg/content/src/nsSVGGraphicElement.cpp
+++ b/content/svg/content/src/nsSVGGraphicElement.cpp
@@ -224,16 +224,20 @@ nsSVGGraphicElement::PrependLocalTransfo
   }
 
   return result;
 }
 
 void
 nsSVGGraphicElement::SetAnimateMotionTransform(const gfxMatrix* aMatrix)
 {
+  if ((!aMatrix && !mAnimateMotionTransform) ||
+      aMatrix && mAnimateMotionTransform && *aMatrix == *mAnimateMotionTransform) {
+    return;
+  }
   mAnimateMotionTransform = aMatrix ? new gfxMatrix(*aMatrix) : nsnull;
   DidAnimateTransformList();
 }
 
 SVGAnimatedTransformList*
 nsSVGGraphicElement::GetAnimatedTransformList()
 {
   if (!mTransforms) {
--- a/gfx/thebes/gfxMatrix.h
+++ b/gfx/thebes/gfxMatrix.h
@@ -60,16 +60,31 @@ public:
 
     /**
      * Multiplies *this with m and returns the result.
      */
     gfxMatrix operator * (const gfxMatrix& m) const {
         return gfxMatrix(*this).Multiply(m);
     }
 
+    /* Returns true if the other matrix is fuzzy-equal to this matrix.
+     * Note that this isn't a cheap comparison!
+     */
+    bool operator==(const gfxMatrix& other) const
+    {
+      return FuzzyEqual(xx, other.xx) && FuzzyEqual(yx, other.yx) &&
+             FuzzyEqual(xy, other.xy) && FuzzyEqual(yy, other.yy) &&
+             FuzzyEqual(x0, other.x0) && FuzzyEqual(y0, other.y0);
+    }
+
+    bool operator!=(const gfxMatrix& other) const
+    {
+      return !(*this == other);
+    }
+
     // matrix operations
     /**
      * Resets this matrix to the identity matrix.
      */
     const gfxMatrix& Reset();
 
     bool IsIdentity() const {
        return xx == 1.0 && yx == 0.0 &&