b=932400 remove refcount manipulation of streams when reordering for processing r=roc
authorKarl Tomlinson <karlt+@karlt.net>
Mon, 07 Jul 2014 11:52:25 +1200
changeset 216752 04019eb4d1b503d1fa9291987fb2b4adec57a11d
parent 216751 a9d2ca71f904b9fbd8afaec44e8f662cd121f124
child 216753 013907ce316a23854600c839368eca67dd1ad986
push id515
push userraliiev@mozilla.com
push dateMon, 06 Oct 2014 12:51:51 +0000
treeherdermozilla-release@267c7a481bef [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs932400
milestone33.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
b=932400 remove refcount manipulation of streams when reordering for processing r=roc
content/media/MediaStreamGraph.cpp
content/media/MediaStreamGraphImpl.h
--- a/content/media/MediaStreamGraph.cpp
+++ b/content/media/MediaStreamGraph.cpp
@@ -85,17 +85,17 @@ MediaStreamGraphImpl::FinishStream(Media
 
   SetStreamOrderDirty();
 }
 
 void
 MediaStreamGraphImpl::AddStream(MediaStream* aStream)
 {
   aStream->mBufferStartTime = mCurrentTime;
-  *mStreams.AppendElement() = already_AddRefed<MediaStream>(aStream);
+  mStreams.AppendElement(aStream);
   STREAM_LOG(PR_LOG_DEBUG, ("Adding media stream %p to the graph", aStream));
 
   SetStreamOrderDirty();
 }
 
 void
 MediaStreamGraphImpl::RemoveStream(MediaStream* aStream)
 {
@@ -108,18 +108,18 @@ MediaStreamGraphImpl::RemoveStream(Media
       if (mStreamUpdates[i].mStream == aStream) {
         mStreamUpdates[i].mStream = nullptr;
       }
     }
   }
 
   SetStreamOrderDirty();
 
-  // This unrefs the stream, probably destroying it
   mStreams.RemoveElement(aStream);
+  NS_RELEASE(aStream); // probably destroying it
 
   STREAM_LOG(PR_LOG_DEBUG, ("Removing media stream %p from the graph", aStream));
 }
 
 void
 MediaStreamGraphImpl::UpdateConsumptionState(SourceMediaStream* aStream)
 {
   MediaStreamListener::Consumption state =
@@ -527,19 +527,19 @@ MediaStreamGraphImpl::MarkConsumed(Media
   // Mark all the inputs to this stream as consumed
   for (uint32_t i = 0; i < ps->mInputs.Length(); ++i) {
     MarkConsumed(ps->mInputs[i]->mSource);
   }
 }
 
 void
 MediaStreamGraphImpl::UpdateStreamOrderForStream(mozilla::LinkedList<MediaStream>* aStack,
-                                                 already_AddRefed<MediaStream> aStream)
+                                                 MediaStream* aStream)
 {
-  nsRefPtr<MediaStream> stream = aStream;
+  MediaStream* stream = aStream;
   NS_ASSERTION(!stream->mHasBeenOrdered, "stream should not have already been ordered");
   if (stream->mIsOnOrderingStack) {
     MediaStream* iter = aStack->getLast();
     AudioNodeStream* ns = stream->AsAudioNodeStream();
     bool delayNodePresent = ns ? ns->Engine()->AsDelayNodeEngine() != nullptr : false;
     bool cycleFound = false;
     if (iter) {
       do {
@@ -577,26 +577,25 @@ MediaStreamGraphImpl::UpdateStreamOrderF
   }
   ProcessedMediaStream* ps = stream->AsProcessedStream();
   if (ps) {
     aStack->insertBack(stream);
     stream->mIsOnOrderingStack = true;
     for (uint32_t i = 0; i < ps->mInputs.Length(); ++i) {
       MediaStream* source = ps->mInputs[i]->mSource;
       if (!source->mHasBeenOrdered) {
-        nsRefPtr<MediaStream> s = source;
-        UpdateStreamOrderForStream(aStack, s.forget());
+        UpdateStreamOrderForStream(aStack, source);
       }
     }
     aStack->popLast();
     stream->mIsOnOrderingStack = false;
   }
 
   stream->mHasBeenOrdered = true;
-  *mStreams.AppendElement() = stream.forget();
+  *mStreams.AppendElement() = stream;
 }
 
 static void AudioMixerCallback(AudioDataValue* aMixedBuffer,
                                AudioSampleFormat aFormat,
                                uint32_t aChannels,
                                uint32_t aFrames,
                                uint32_t aSampleRate)
 {
@@ -641,22 +640,22 @@ MediaStreamGraphImpl::UpdateStreamOrder(
   if (!mMixer && shouldMix) {
     mMixer = new AudioMixer(AudioMixerCallback);
   } else if (mMixer && !shouldMix) {
     mMixer = nullptr;
   }
 
   mozilla::LinkedList<MediaStream> stack;
   for (uint32_t i = 0; i < mOldStreams.Length(); ++i) {
-    nsRefPtr<MediaStream>& s = mOldStreams[i];
+    MediaStream* s = mOldStreams[i];
     if (s->IsIntrinsicallyConsumed()) {
       MarkConsumed(s);
     }
     if (!s->mHasBeenOrdered) {
-      UpdateStreamOrderForStream(&stack, s.forget());
+      UpdateStreamOrderForStream(&stack, s);
     }
   }
 }
 
 void
 MediaStreamGraphImpl::RecomputeBlocking(GraphTime aEndBlockingDecisions)
 {
   bool blockingDecisionsWillChange = false;
--- a/content/media/MediaStreamGraphImpl.h
+++ b/content/media/MediaStreamGraphImpl.h
@@ -232,17 +232,17 @@ public:
    * Update "have enough data" flags in aStream.
    */
   void UpdateBufferSufficiencyState(SourceMediaStream* aStream);
   /*
    * If aStream hasn't already been ordered, push it onto aStack and order
    * its children.
    */
   void UpdateStreamOrderForStream(mozilla::LinkedList<MediaStream>* aStack,
-                                  already_AddRefed<MediaStream> aStream);
+                                  MediaStream* aStream);
   /**
    * Mark aStream and all its inputs (recursively) as consumed.
    */
   static void MarkConsumed(MediaStream* aStream);
   /**
    * Sort mStreams so that every stream not in a cycle is after any streams
    * it depends on, and every stream in a cycle is marked as being in a cycle.
    * Also sets mIsConsumed on every stream.
@@ -421,22 +421,27 @@ public:
    * Readonly after initialization on the main thread.
    */
   nsCOMPtr<nsIThread> mThread;
 
   // The following state is managed on the graph thread only, unless
   // mLifecycleState > LIFECYCLE_RUNNING in which case the graph thread
   // is not running and this state can be used from the main thread.
 
-  nsTArray<nsRefPtr<MediaStream> > mStreams;
+  /**
+   * The graph keeps a reference to each stream.
+   * References are maintained manually to simplify reordering without
+   * unnecessary thread-safe refcount changes.
+   */
+  nsTArray<MediaStream*> mStreams;
   /**
    * mOldStreams is used as temporary storage for streams when computing the
    * order in which we compute them.
    */
-  nsTArray<nsRefPtr<MediaStream> > mOldStreams;
+  nsTArray<MediaStream*> mOldStreams;
   /**
    * The current graph time for the current iteration of the RunThread control
    * loop.
    */
   GraphTime mCurrentTime;
   /**
    * Blocking decisions and all stream contents have been computed up to this
    * time. The next batch of updates from the main thread will be processed