Bug 1425150 - Register AudioCallbackDriver to the Gecko Profiler. r?jya draft
authorPaul Adenot <paul@paul.cx>
Wed, 13 Dec 2017 17:10:14 -0600
changeset 711529 e57fae45f9e8d86bba84bda77c73ea5f0bef6fb2
parent 711528 104d8a327353bef69e2dba4cd97f453a3ff5adbb
child 743812 77d724c6b93e93b6a8e4a03b7cc1f0449e69565b
push id93073
push userpaul@paul.cx
push dateWed, 13 Dec 2017 23:10:45 +0000
reviewersjya
bugs1425150
milestone59.0a1
Bug 1425150 - Register AudioCallbackDriver to the Gecko Profiler. r?jya MozReview-Commit-ID: 3rJbF8Kq0zx
dom/media/GraphDriver.cpp
dom/media/GraphDriver.h
--- a/dom/media/GraphDriver.cpp
+++ b/dom/media/GraphDriver.cpp
@@ -534,16 +534,17 @@ AudioCallbackDriver::AudioCallbackDriver
   , mIterationDurationMS(MEDIA_GRAPH_TARGET_PERIOD_MS)
   , mStarted(false)
   , mAudioInput(nullptr)
   , mAddedMixer(false)
   , mInCallback(false)
   , mMicrophoneActive(false)
   , mShouldFallbackIfError(false)
   , mFromFallback(false)
+  , mProfilerRegistered(false)
 {
   LOG(LogLevel::Debug, ("AudioCallbackDriver ctor for graph %p", aGraphImpl));
 #if defined(XP_WIN)
   if (XRE_IsContentProcess()) {
     audio::AudioNotificationReceiver::Register(this);
   }
 #endif
 }
@@ -892,16 +893,21 @@ AudioCallbackDriver::DataCallback(const 
 
 #ifdef DEBUG
   // DebugOnly<> doesn't work here... it forces an initialization that will cause
   // mInCallback to be set back to false before we exit the statement.  Do it by
   // hand instead.
   AutoInCallback aic(this);
 #endif
 
+  if (!mProfilerRegistered) {
+    mProfilerRegistered = true;
+    PROFILER_REGISTER_THREAD("AudioCallback");
+  }
+
   GraphTime stateComputedTime = StateComputedTime();
   if (stateComputedTime == 0) {
     MonitorAutoLock mon(mGraphImpl->GetMonitor());
     // Because this function is called during cubeb_stream_init (to prefill the
     // audio buffers), it can be that we don't have a message here (because this
     // driver is the first one for this graph), and the graph would exit. Simply
     // return here until we have messages.
     if (!mGraphImpl->MessagesQueued()) {
@@ -997,16 +1003,18 @@ AudioCallbackDriver::DataCallback(const 
   if (!stillProcessing) {
     // About to hand over control of the graph.  Do not start a new driver if
     // StateCallback() receives an error for this stream while the main thread
     // or another driver has control of the graph.
     mShouldFallbackIfError = false;
     // Enter shutdown mode. The stable-state handler will detect this
     // and complete shutdown if the graph does not get restarted.
     mGraphImpl->SignalMainThreadCleanup();
+
+    PROFILER_UNREGISTER_THREAD();
     return aFrames - 1;
   }
 
   bool switching = false;
   {
     MonitorAutoLock mon(mGraphImpl->GetMonitor());
     switching = !!NextDriver();
   }
@@ -1019,16 +1027,17 @@ AudioCallbackDriver::DataCallback(const 
     if (!IsStarted()) {
       return aFrames;
     }
     LOG(LogLevel::Debug, ("Switching to system driver."));
     RemoveCallback();
     NextDriver()->SetGraphTime(this, mIterationStart, mIterationEnd);
     mGraphImpl->SetCurrentDriver(NextDriver());
     NextDriver()->Start();
+    PROFILER_UNREGISTER_THREAD();
     // Returning less than aFrames starts the draining and eventually stops the
     // audio thread. This function will never get called again.
     return aFrames - 1;
   }
 
   return aFrames;
 }
 
@@ -1110,16 +1119,18 @@ AudioCallbackDriver::DeviceChangedCallba
   // state.
   MonitorAutoLock mon(mGraphImpl->GetMonitor());
   if (mAudioInput) {
     mAudioInput->DeviceChanged();
   }
 #ifdef XP_MACOSX
   PanOutputIfNeeded(mMicrophoneActive);
 #endif
+
+  mProfilerRegistered = false;
 }
 
 void
 AudioCallbackDriver::SetMicrophoneActive(bool aActive)
 {
   mMicrophoneActive = aActive;
 
 #ifdef XP_MACOSX
--- a/dom/media/GraphDriver.h
+++ b/dom/media/GraphDriver.h
@@ -561,16 +561,22 @@ private:
    * After transitioning to false on the last DataCallback(), the stream is
    * not accessed from another thread until the graph thread either signals
    * main thread cleanup or dispatches an event to switch to another
    * driver. */
   bool mShouldFallbackIfError;
   /* True if this driver was created from a driver created because of a previous
    * AudioCallbackDriver failure. */
   bool mFromFallback;
+  /* Whether or not the Gecko profiler has been registered for this thread.
+   * We reset this on device change, because the underlying thread is going to
+   * change.
+   * We de-register on the last iteration, and re-register on the first
+   * iteration of a new driver. */
+  Atomic<bool> mProfilerRegistered;
 };
 
 class AsyncCubebTask : public Runnable
 {
 public:
 
   AsyncCubebTask(AudioCallbackDriver* aDriver, AsyncCubebOperation aOperation);