Bug 853246 - Optimize Panner and Listener methods when processing them would not have a significant effect; r=roc
authorEhsan Akhgari <ehsan@mozilla.com>
Wed, 20 Mar 2013 20:12:07 -0400
changeset 136106 df7a8ab4ffed956ffa5170ae7a5275595dc0272a
parent 136105 176b8aa6844d2e49abcb88e11de785a080ffc5b5
child 136107 eb6bef1edb39c83d79f436a25d0aa4945da0dd01
push id2452
push userlsblakk@mozilla.com
push dateMon, 13 May 2013 16:59:38 +0000
treeherdermozilla-beta@d4b152d29d8d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs853246
milestone22.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 853246 - Optimize Panner and Listener methods when processing them would not have a significant effect; r=roc
content/media/webaudio/AudioListener.h
content/media/webaudio/AudioParam.h
content/media/webaudio/Makefile.in
content/media/webaudio/PannerNode.h
content/media/webaudio/WebAudioUtils.h
--- a/content/media/webaudio/AudioListener.h
+++ b/content/media/webaudio/AudioListener.h
@@ -10,16 +10,17 @@
 #include "nsWrapperCache.h"
 #include "nsCycleCollectionParticipant.h"
 #include "mozilla/Attributes.h"
 #include "EnableWebAudioCheck.h"
 #include "nsAutoPtr.h"
 #include "ThreeDPoint.h"
 #include "AudioContext.h"
 #include "PannerNode.h"
+#include "WebAudioUtils.h"
 
 struct JSContext;
 
 namespace mozilla {
 
 namespace dom {
 
 class AudioContext;
@@ -41,53 +42,77 @@ public:
   virtual JSObject* WrapObject(JSContext* aCx, JSObject* aScope) MOZ_OVERRIDE;
 
   double DopplerFactor() const
   {
     return mDopplerFactor;
   }
   void SetDopplerFactor(double aDopplerFactor)
   {
+    if (WebAudioUtils::FuzzyEqual(mDopplerFactor, aDopplerFactor)) {
+      return;
+    }
     mDopplerFactor = aDopplerFactor;
     SendDoubleParameterToStream(PannerNode::LISTENER_DOPPLER_FACTOR, mDopplerFactor);
   }
 
   double SpeedOfSound() const
   {
     return mSpeedOfSound;
   }
   void SetSpeedOfSound(double aSpeedOfSound)
   {
+    if (WebAudioUtils::FuzzyEqual(mSpeedOfSound, aSpeedOfSound)) {
+      return;
+    }
     mSpeedOfSound = aSpeedOfSound;
     SendDoubleParameterToStream(PannerNode::LISTENER_SPEED_OF_SOUND, mSpeedOfSound);
   }
 
   void SetPosition(double aX, double aY, double aZ)
   {
+    if (WebAudioUtils::FuzzyEqual(mPosition.x, aX) &&
+        WebAudioUtils::FuzzyEqual(mPosition.y, aY) &&
+        WebAudioUtils::FuzzyEqual(mPosition.z, aZ)) {
+      return;
+    }
     mPosition.x = aX;
     mPosition.y = aY;
     mPosition.z = aZ;
     SendThreeDPointParameterToStream(PannerNode::LISTENER_POSITION, mPosition);
   }
 
   void SetOrientation(double aX, double aY, double aZ,
                       double aXUp, double aYUp, double aZUp)
   {
+    if (WebAudioUtils::FuzzyEqual(mOrientation.x, aX) &&
+        WebAudioUtils::FuzzyEqual(mOrientation.y, aY) &&
+        WebAudioUtils::FuzzyEqual(mOrientation.z, aZ) &&
+        WebAudioUtils::FuzzyEqual(mUpVector.x, aX) &&
+        WebAudioUtils::FuzzyEqual(mUpVector.y, aY) &&
+        WebAudioUtils::FuzzyEqual(mUpVector.z, aZ)) {
+      return;
+    }
     mOrientation.x = aX;
     mOrientation.y = aY;
     mOrientation.z = aZ;
     mUpVector.x = aXUp;
     mUpVector.y = aYUp;
     mUpVector.z = aZUp;
     SendThreeDPointParameterToStream(PannerNode::LISTENER_ORIENTATION, mOrientation);
     SendThreeDPointParameterToStream(PannerNode::LISTENER_UPVECTOR, mUpVector);
   }
 
   void SetVelocity(double aX, double aY, double aZ)
   {
+    if (WebAudioUtils::FuzzyEqual(mVelocity.x, aX) &&
+        WebAudioUtils::FuzzyEqual(mVelocity.y, aY) &&
+        WebAudioUtils::FuzzyEqual(mVelocity.z, aZ)) {
+      return;
+    }
     mVelocity.x = aX;
     mVelocity.y = aY;
     mVelocity.z = aZ;
     SendThreeDPointParameterToStream(PannerNode::LISTENER_VELOCITY, mVelocity);
   }
 
   void RegisterPannerNode(PannerNode* aPannerNode);
 
--- a/content/media/webaudio/AudioParam.h
+++ b/content/media/webaudio/AudioParam.h
@@ -12,16 +12,17 @@
 #include "nsCycleCollectionParticipant.h"
 #include "nsCOMPtr.h"
 #include "EnableWebAudioCheck.h"
 #include "nsAutoPtr.h"
 #include "AudioNode.h"
 #include "mozilla/dom/TypedArray.h"
 #include "mozilla/Util.h"
 #include "mozilla/ErrorResult.h"
+#include "WebAudioUtils.h"
 
 struct JSContext;
 class nsIDOMWindow;
 
 namespace mozilla {
 
 namespace dom {
 
@@ -60,17 +61,18 @@ public:
     mCallback(mNode);
   }
 
   // We override the rest of the mutating AudioParamTimeline methods in order to make
   // sure that the callback is called every time that this object gets mutated.
   void SetValue(float aValue)
   {
     // Optimize away setting the same value on an AudioParam
-    if (HasSimpleValue() && fabsf(GetValue() - aValue) < 1e-7) {
+    if (HasSimpleValue() &&
+        WebAudioUtils::FuzzyEqual(GetValue(), aValue)) {
       return;
     }
     AudioParamTimeline::SetValue(aValue);
     mCallback(mNode);
   }
   void SetValueAtTime(float aValue, double aStartTime, ErrorResult& aRv)
   {
     AudioParamTimeline::SetValueAtTime(aValue, aStartTime, aRv);
--- a/content/media/webaudio/Makefile.in
+++ b/content/media/webaudio/Makefile.in
@@ -49,13 +49,14 @@ EXPORTS_mozilla/dom := \
   EnableWebAudioCheck.h \
   GainNode.h \
   PannerNode.h \
   $(NULL)
 
 EXPORTS := \
   MediaBufferDecoder.h \
   ThreeDPoint.h \
+  WebAudioUtils.h \
   $(NULL)
 
 FORCE_STATIC_LIB := 1
 
 include $(topsrcdir)/config/rules.mk
--- a/content/media/webaudio/PannerNode.h
+++ b/content/media/webaudio/PannerNode.h
@@ -9,16 +9,17 @@
 
 #include "AudioNode.h"
 #include "AudioParam.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/TypedEnum.h"
 #include "mozilla/dom/PannerNodeBinding.h"
 #include "ThreeDPoint.h"
 #include "mozilla/WeakPtr.h"
+#include "WebAudioUtils.h"
 
 namespace mozilla {
 namespace dom {
 
 class AudioContext;
 
 class PannerNode : public AudioNode,
                    public SupportsWeakPtr<PannerNode>
@@ -51,94 +52,127 @@ public:
   void SetDistanceModel(DistanceModelType aDistanceModel)
   {
     mDistanceModel = aDistanceModel;
     SendInt32ParameterToStream(DISTANCE_MODEL, int32_t(mDistanceModel));
   }
 
   void SetPosition(double aX, double aY, double aZ)
   {
+    if (WebAudioUtils::FuzzyEqual(mPosition.x, aX) &&
+        WebAudioUtils::FuzzyEqual(mPosition.y, aY) &&
+        WebAudioUtils::FuzzyEqual(mPosition.z, aZ)) {
+      return;
+    }
     mPosition.x = aX;
     mPosition.y = aY;
     mPosition.z = aZ;
     SendThreeDPointParameterToStream(POSITION, mPosition);
   }
 
   void SetOrientation(double aX, double aY, double aZ)
   {
+    if (WebAudioUtils::FuzzyEqual(mOrientation.x, aX) &&
+        WebAudioUtils::FuzzyEqual(mOrientation.y, aY) &&
+        WebAudioUtils::FuzzyEqual(mOrientation.z, aZ)) {
+      return;
+    }
     mOrientation.x = aX;
     mOrientation.y = aY;
     mOrientation.z = aZ;
     SendThreeDPointParameterToStream(ORIENTATION, mOrientation);
   }
 
   void SetVelocity(double aX, double aY, double aZ)
   {
+    if (WebAudioUtils::FuzzyEqual(mVelocity.x, aX) &&
+        WebAudioUtils::FuzzyEqual(mVelocity.y, aY) &&
+        WebAudioUtils::FuzzyEqual(mVelocity.z, aZ)) {
+      return;
+    }
     mVelocity.x = aX;
     mVelocity.y = aY;
     mVelocity.z = aZ;
     SendThreeDPointParameterToStream(VELOCITY, mVelocity);
   }
 
   double RefDistance() const
   {
     return mRefDistance;
   }
   void SetRefDistance(double aRefDistance)
   {
+    if (WebAudioUtils::FuzzyEqual(mRefDistance, aRefDistance)) {
+      return;
+    }
     mRefDistance = aRefDistance;
     SendDoubleParameterToStream(REF_DISTANCE, mRefDistance);
   }
 
   double MaxDistance() const
   {
     return mMaxDistance;
   }
   void SetMaxDistance(double aMaxDistance)
   {
+    if (WebAudioUtils::FuzzyEqual(mMaxDistance, aMaxDistance)) {
+      return;
+    }
     mMaxDistance = aMaxDistance;
     SendDoubleParameterToStream(MAX_DISTANCE, mMaxDistance);
   }
 
   double RolloffFactor() const
   {
     return mRolloffFactor;
   }
   void SetRolloffFactor(double aRolloffFactor)
   {
+    if (WebAudioUtils::FuzzyEqual(mRolloffFactor, aRolloffFactor)) {
+      return;
+    }
     mRolloffFactor = aRolloffFactor;
     SendDoubleParameterToStream(ROLLOFF_FACTOR, mRolloffFactor);
   }
 
   double ConeInnerAngle() const
   {
     return mConeInnerAngle;
   }
   void SetConeInnerAngle(double aConeInnerAngle)
   {
+    if (WebAudioUtils::FuzzyEqual(mConeInnerAngle, aConeInnerAngle)) {
+      return;
+    }
     mConeInnerAngle = aConeInnerAngle;
     SendDoubleParameterToStream(CONE_INNER_ANGLE, mConeInnerAngle);
   }
 
   double ConeOuterAngle() const
   {
     return mConeOuterAngle;
   }
   void SetConeOuterAngle(double aConeOuterAngle)
   {
+    if (WebAudioUtils::FuzzyEqual(mConeOuterAngle, aConeOuterAngle)) {
+      return;
+    }
     mConeOuterAngle = aConeOuterAngle;
     SendDoubleParameterToStream(CONE_OUTER_ANGLE, mConeOuterAngle);
   }
 
   double ConeOuterGain() const
   {
     return mConeOuterGain;
   }
   void SetConeOuterGain(double aConeOuterGain)
   {
+    if (WebAudioUtils::FuzzyEqual(mConeOuterGain, aConeOuterGain)) {
+      return;
+    }
     mConeOuterGain = aConeOuterGain;
     SendDoubleParameterToStream(CONE_OUTER_GAIN, mConeOuterGain);
   }
 
 private:
   friend class AudioListener;
   friend class PannerNodeEngine;
   enum EngineParameters {
new file mode 100644
--- /dev/null
+++ b/content/media/webaudio/WebAudioUtils.h
@@ -0,0 +1,33 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* 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/. */
+
+#ifndef WebAudioUtils_h_
+#define WebAudioUtils_h_
+
+#include <cmath>
+
+namespace mozilla {
+
+namespace dom {
+
+struct WebAudioUtils {
+  static bool FuzzyEqual(float v1, float v2)
+  {
+    using namespace std;
+    return fabsf(v1 - v2) < 1e-7f;
+  }
+  static bool FuzzyEqual(double v1, double v2)
+  {
+    using namespace std;
+    return fabs(v1 - v2) < 1e-7;
+  }
+};
+
+}
+}
+
+#endif
+