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 99658 123be65017577f98542852fc557efa66581100f7
parent 99657 0865e37d8cad23da3563664ebfaca458b11ea95b
child 99659 2f9736a307557c7d18c2c443a27a7ee4d5a9befe
push id1116
push userlsblakk@mozilla.com
push dateMon, 16 Jul 2012 19:38:18 +0000
treeherdermozilla-beta@95f959a8b4dc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert
bugs758505
milestone15.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 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 &&