Bug 1273009 - Prune AudioParam events in the main thread when inserting new events. r?karlt draft
authorPaul Adenot <paul@paul.cx>
Wed, 29 Jun 2016 10:25:58 +0200
changeset 382221 ad123174e027f0ea90c897eb47982463b0a937ef
parent 382220 753aafa4b6765059569022802c2f7e11ace781be
child 524133 21fd04706eff382d6e4b1fd7bd06ae8290260994
push id21657
push userbmo:padenot@mozilla.com
push dateWed, 29 Jun 2016 08:29:04 +0000
reviewerskarlt
bugs1273009
milestone50.0a1
Bug 1273009 - Prune AudioParam events in the main thread when inserting new events. r?karlt Running the test-case in the bug, and profiling under OSX using Instruments' time profiler, the time spent in `AudioEventTimeline::ValidateEvent` was the highest Web Audio API-related function. This patch makes it disappear from the profile. We already use the same technique on the MSG thread to keep the number of events low. MozReview-Commit-ID: GJLPRWBh7nQ
dom/media/webaudio/AudioEventTimeline.h
dom/media/webaudio/AudioParam.cpp
dom/media/webaudio/AudioParam.h
--- a/dom/media/webaudio/AudioEventTimeline.h
+++ b/dom/media/webaudio/AudioEventTimeline.h
@@ -331,17 +331,17 @@ public:
   }
 
   // Return the number of events scheduled
   uint32_t GetEventCount() const
   {
     return mEvents.Length();
   }
 
-private:
+protected:
   template<class TimeType>
   void GetValuesAtTimeHelper(TimeType aTime, float* aBuffer, const size_t aSize);
 
   template<class TimeType>
   float GetValuesAtTimeHelperInternal(TimeType aTime,
                                       const AudioTimelineEvent* aPrevious,
                                       const AudioTimelineEvent* aNext);
 
--- a/dom/media/webaudio/AudioParam.cpp
+++ b/dom/media/webaudio/AudioParam.cpp
@@ -156,16 +156,30 @@ AudioParam::SendEventToEngine(const Audi
                       "duration" : "constant",
                     aEvent.mType == AudioTimelineEvent::SetValueCurve ?
                       aEvent.mDuration : aEvent.mTimeConstant);
 
   AudioNodeStream* stream = mNode->GetStream();
   if (stream) {
     stream->SendTimelineEvent(mIndex, aEvent);
   }
+
+  CleanupOldEvents();
+}
+
+void
+AudioParam::CleanupOldEvents()
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  double currentTime = mNode->Context()->CurrentTime();
+
+  while (mEvents.Length() > 1 &&
+         currentTime > mEvents[1].template Time<double>()) {
+    mEvents.RemoveElementAt(0);
+  }
 }
 
 float
 AudioParamTimeline::AudioNodeInputValue(size_t aCounter) const
 {
   MOZ_ASSERT(mStream);
 
   // If we have a chunk produced by the AudioNode inputs to the AudioParam,
--- a/dom/media/webaudio/AudioParam.h
+++ b/dom/media/webaudio/AudioParam.h
@@ -216,16 +216,17 @@ private:
     AudioEventTimeline::InsertEvent<double>(event);
 
     SendEventToEngine(event);
   }
 
   void SendEventToEngine(const AudioTimelineEvent& aEvent);
 
   void DisconnectFromGraphAndDestroyStream();
+  void CleanupOldEvents();
 
   nsCycleCollectingAutoRefCnt mRefCnt;
   NS_DECL_OWNINGTHREAD
   RefPtr<AudioNode> mNode;
   // For every InputNode, there is a corresponding entry in mOutputParams of the
   // InputNode's mInputNode.
   nsTArray<AudioNode::InputNode> mInputNodes;
   const char* mName;