Bug 1425150 - Register AudioCallbackDriver to the Gecko Profiler. r?jya
MozReview-Commit-ID: 3rJbF8Kq0zx
--- 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);