diff --git a/content/smil/nsSMILAnimationFunction.cpp b/content/smil/nsSMILAnimationFunction.cpp index 13cb38ecf75..26fc643516c 100644 --- a/content/smil/nsSMILAnimationFunction.cpp +++ b/content/smil/nsSMILAnimationFunction.cpp @@ -360,6 +360,16 @@ nsSMILAnimationFunction::HasChanged() const return mHasChanged; } +PRBool +nsSMILAnimationFunction::UpdateCachedTarget(const nsSMILTargetIdentifier& aNewTarget) +{ + if (!mLastTarget.Equals(aNewTarget)) { + mLastTarget = aNewTarget; + return PR_TRUE; + } + return PR_FALSE; +} + //---------------------------------------------------------------------- // Implementation helpers diff --git a/content/smil/nsSMILAnimationFunction.h b/content/smil/nsSMILAnimationFunction.h index 877b002b9bb..318dc3fd7fb 100644 --- a/content/smil/nsSMILAnimationFunction.h +++ b/content/smil/nsSMILAnimationFunction.h @@ -42,6 +42,7 @@ #include "nsISMILAttr.h" #include "nsGkAtoms.h" #include "nsString.h" +#include "nsSMILTargetIdentifier.h" #include "nsSMILTimeValue.h" #include "nsSMILKeySpline.h" #include "nsSMILValue.h" @@ -207,14 +208,28 @@ public: * time it was composited. This allows rendering to be performed only when * necessary, particularly when no animations are active. * - * Note that the caller is responsible for determining if the animation target - * has changed. + * Note that the caller is responsible for determining if the animation + * target has changed (with help from my UpdateCachedTarget() method). * * @return PR_TRUE if the animation parameters have changed, PR_FALSE * otherwise. */ PRBool HasChanged() const; + /** + * Updates the cached record of our animation target, and returns a boolean + * that indicates whether the target has changed since the last call to this + * function. (This lets nsSMILCompositor check whether its animation + * functions have changed value or target since the last sample. If none of + * them have, then the compositor doesn't need to do anything.) + * + * @param aNewTarget A nsSMILTargetIdentifier representing the animation + * target of this function for this sample. + * @return PR_TRUE if |aNewTarget| is different from the old cached value; + * otherwise, PR_FALSE. + */ + PRBool UpdateCachedTarget(const nsSMILTargetIdentifier& aNewTarget); + // Comparator utility class, used for sorting nsSMILAnimationFunctions class Comparator { public: @@ -378,6 +393,11 @@ protected: // @see // http://www.w3.org/TR/2001/REC-smil-animation-20010904/#FromToByAndAdditive nsSMILValue mFrozenValue; + + // Allows us to check whether an animation function has changed target from + // sample to sample (because if neither target nor animated value have + // changed, we don't have to do anything). + nsSMILWeakTargetIdentifier mLastTarget; }; #endif // NS_SMILANIMATIONFUNCTION_H_ diff --git a/content/smil/nsSMILCompositor.cpp b/content/smil/nsSMILCompositor.cpp index 98c3ec81558..3d094210570 100644 --- a/content/smil/nsSMILCompositor.cpp +++ b/content/smil/nsSMILCompositor.cpp @@ -114,24 +114,15 @@ nsSMILCompositor::ComposeAttribute() // THIRD: Step backwards through animation functions to find out // which ones we actually care about. - // PRBool changed = PR_FALSE; // XXXdholbert removing until we have - // HasChangedTarget + PRBool changed = PR_FALSE; PRUint32 length = mAnimationFunctions.Length(); PRUint32 i; for (i = length; i > 0; --i) { nsSMILAnimationFunction* curAnimFunc = mAnimationFunctions[i-1]; - // XXXdholbert we need to add another function - // nsSMILAnimationFunction::HasChangedTarget(elem, smilAttr, isCSS) that - // we call here (in addition to HasChanged(), because even if function - // value hasn't changed, its target might have. - // For this to work, the nsSMILAnimationFunction needs to cache its last - // elem/smilAttr/isCSS values, and then check them against the new values - // here. - /* - if (!changed && curAnimFunc->HasChanged()) { + if (curAnimFunc->UpdateCachedTarget(mKey) || + (!changed && curAnimFunc->HasChanged())) { changed = PR_TRUE; } - */ if (curAnimFunc->WillReplace()) { --i; @@ -141,7 +132,7 @@ nsSMILCompositor::ComposeAttribute() // NOTE: 'i' is now the index of the first animation function that we need // to use in compositing. - // if (!changed) // XXXdholbert removing until we have HasChangedTarget + // if (!changed) // XXXdholbert Still need to enable this optimization // return; // FOURTH: Compose animation functions (starting with base value)