Bug 883010 - Optimize MediaStreamGraphImpl::UpdateStreamOrder in order to optimize away how much time we spend on it in every iteration of the MSG. r=roc
authorPaul Adenot <paul@paul.cx>
Wed, 29 Jan 2014 14:34:35 +0100
changeset 166948 090d90e542df8d61ba7c533a3279d9a227c985fa
parent 166947 b5e50392da12d32881ba72a51dcb016181b93ecb
child 166949 357895a6aaac9c4b4c4e545712a3e899fbfbaa1a
push id39331
push userpaul@paul.cx
push dateWed, 05 Feb 2014 13:58:57 +0000
treeherdermozilla-inbound@090d90e542df [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs883010
milestone30.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 883010 - Optimize MediaStreamGraphImpl::UpdateStreamOrder in order to optimize away how much time we spend on it in every iteration of the MSG. r=roc
content/media/MediaStreamGraph.cpp
--- a/content/media/MediaStreamGraph.cpp
+++ b/content/media/MediaStreamGraph.cpp
@@ -67,24 +67,28 @@ MediaStreamGraphImpl::FinishStream(Media
   if (aStream->mFinished)
     return;
   STREAM_LOG(PR_LOG_DEBUG, ("MediaStream %p will finish", aStream));
   aStream->mFinished = true;
   // Force at least one more iteration of the control loop, since we rely
   // on UpdateCurrentTime to notify our listeners once the stream end
   // has been reached.
   EnsureNextIteration();
+
+  SetStreamOrderDirty();
 }
 
 void
 MediaStreamGraphImpl::AddStream(MediaStream* aStream)
 {
   aStream->mBufferStartTime = mCurrentTime;
   *mStreams.AppendElement() = already_AddRefed<MediaStream>(aStream);
   STREAM_LOG(PR_LOG_DEBUG, ("Adding media stream %p to the graph", aStream));
+
+  SetStreamOrderDirty();
 }
 
 void
 MediaStreamGraphImpl::RemoveStream(MediaStream* aStream)
 {
   // Remove references in mStreamUpdates before we allow aStream to die.
   // Pending updates are not needed (since the main thread has already given
   // up the stream) so we will just drop them.
@@ -92,16 +96,18 @@ MediaStreamGraphImpl::RemoveStream(Media
     MonitorAutoLock lock(mMonitor);
     for (uint32_t i = 0; i < mStreamUpdates.Length(); ++i) {
       if (mStreamUpdates[i].mStream == aStream) {
         mStreamUpdates[i].mStream = nullptr;
       }
     }
   }
 
+  SetStreamOrderDirty();
+
   // This unrefs the stream, probably destroying it
   mStreams.RemoveElement(aStream);
 
   STREAM_LOG(PR_LOG_DEBUG, ("Removing media stream %p from the graph", aStream));
 }
 
 void
 MediaStreamGraphImpl::UpdateConsumptionState(SourceMediaStream* aStream)
@@ -425,16 +431,17 @@ MediaStreamGraphImpl::UpdateCurrentTime(
   for (uint32_t i = 0; i < streamsReadyToFinish.Length(); ++i) {
     MediaStream* stream = streamsReadyToFinish[i];
     // The stream is fully finished when all of its track data has been played
     // out.
     if (mCurrentTime >=
           stream->StreamTimeToGraphTime(stream->GetStreamBuffer().GetAllTracksEnd()))  {
       stream->mNotifiedFinished = true;
       stream->mLastPlayedVideoFrame.SetNull();
+      SetStreamOrderDirty();
       for (uint32_t j = 0; j < stream->mListeners.Length(); ++j) {
         MediaStreamListener* l = stream->mListeners[j];
         l->NotifyFinished(this);
       }
     }
   }
 }
 
@@ -1163,17 +1170,19 @@ MediaStreamGraphImpl::RunThread()
       nsTArray<nsAutoPtr<ControlMessage> >& messages = messageQueue[i].mMessages;
 
       for (uint32_t j = 0; j < messages.Length(); ++j) {
         messages[j]->Run();
       }
     }
     messageQueue.Clear();
 
-    UpdateStreamOrder();
+    if (mStreamOrderDirty) {
+      UpdateStreamOrder();
+    }
 
     // Find the sampling rate that we need to use for non-realtime graphs.
     TrackRate sampleRate = IdealAudioRate();
     if (!mRealtime) {
       for (uint32_t i = 0; i < mStreams.Length(); ++i) {
         AudioNodeStream* n = mStreams[i]->AsAudioNodeStream();
         if (n) {
           // We know that the rest of the streams will run at the same rate.
@@ -2274,16 +2283,18 @@ MediaInputPort::Disconnect()
                "mSource must either both be null or both non-null");
   if (!mSource)
     return;
 
   mSource->RemoveConsumer(this);
   mSource = nullptr;
   mDest->RemoveInput(this);
   mDest = nullptr;
+
+  GraphImpl()->SetStreamOrderDirty();
 }
 
 MediaInputPort::InputInterval
 MediaInputPort::GetNextInputInterval(GraphTime aTime)
 {
   InputInterval result = { GRAPH_TIME_MAX, GRAPH_TIME_MAX, false };
   GraphTime t = aTime;
   GraphTime end;
@@ -2352,16 +2363,17 @@ ProcessedMediaStream::AllocateInputPort(
   public:
     Message(MediaInputPort* aPort)
       : ControlMessage(aPort->GetDestination()),
         mPort(aPort) {}
     virtual void Run()
     {
       mPort->Init();
       // The graph holds its reference implicitly
+      mPort->GraphImpl()->SetStreamOrderDirty();
       mPort.forget();
     }
     virtual void RunDuringShutdown()
     {
       Run();
     }
     nsRefPtr<MediaInputPort> mPort;
   };
@@ -2405,16 +2417,17 @@ ProcessedMediaStream::SetAutofinish(bool
 
 void
 ProcessedMediaStream::DestroyImpl()
 {
   for (int32_t i = mInputs.Length() - 1; i >= 0; --i) {
     mInputs[i]->Disconnect();
   }
   MediaStream::DestroyImpl();
+  GraphImpl()->SetStreamOrderDirty();
 }
 
 /**
  * We make the initial mCurrentTime nonzero so that zero times can have
  * special meaning if necessary.
  */
 static const int32_t INITIAL_CURRENT_TIME = 1;