From daf9a7dbdcecfd14e984cb1cf4a0993c77185286 Mon Sep 17 00:00:00 2001 From: Karl Tomlinson Date: Tue, 30 Oct 2018 15:00:43 +0000 Subject: [PATCH] Bug 1503132 create offline graph thread on receipt of the first message r=padenot With this change, the graph is already running when mEndTime is set and so this must be done on the graph thread for consistent ordering with in-flight messages. Depends on D10168 Differential Revision: https://phabricator.services.mozilla.com/D10169 --HG-- extra : moz-landing-system : lando --- dom/media/MediaStreamGraph.cpp | 50 +++++++++++++++----------------- dom/media/MediaStreamGraphImpl.h | 9 +++--- 2 files changed, 27 insertions(+), 32 deletions(-) diff --git a/dom/media/MediaStreamGraph.cpp b/dom/media/MediaStreamGraph.cpp index c69351126005..bf55d2c493e4 100644 --- a/dom/media/MediaStreamGraph.cpp +++ b/dom/media/MediaStreamGraph.cpp @@ -1526,11 +1526,7 @@ MediaStreamGraphImpl::ForceShutDown(media::ShutdownTicket* aShutdownTicket) mForceShutdownTicket = aShutdownTicket; MonitorAutoLock lock(mMonitor); mForceShutDown = true; - if (IsNonRealtime()) { - // Start the graph if it has not been started already, but don't produce anything. - // This method will return early if the graph is already started. - StartNonRealtimeProcessing(0); - } else if (LifecycleStateRef() == LIFECYCLE_THREAD_NOT_STARTED) { + if (LifecycleStateRef() == LIFECYCLE_THREAD_NOT_STARTED) { // We *could* have just sent this a message to start up, so don't // yank the rug out from under it. Tell it to startup and let it // shut down. @@ -1793,10 +1789,7 @@ MediaStreamGraphImpl::RunInStableState(bool aSourceIsMSG) } } - // Don't start the thread for a non-realtime graph until it has been - // explicitly started by StartNonRealtimeProcessing. - if (LifecycleStateRef() == LIFECYCLE_THREAD_NOT_STARTED && - (mRealtime || mNonRealtimeProcessing)) { + if (LifecycleStateRef() == LIFECYCLE_THREAD_NOT_STARTED) { LifecycleStateRef() = LIFECYCLE_RUNNING; // Start the thread now. We couldn't start it earlier because // the graph might exit immediately on finding it has no streams. The @@ -3673,6 +3666,8 @@ MediaStreamGraphImpl::MediaStreamGraphImpl(GraphDriverType aDriverRequested, AbstractThread* aMainThread) : MediaStreamGraph(aSampleRate) , mFirstCycleBreaker(0) + // An offline graph is not initially processing. + , mEndTime(aDriverRequested == OFFLINE_THREAD_DRIVER ? 0 : GRAPH_TIME_MAX) , mPortCount(0) , mInputDeviceID(nullptr) , mOutputDeviceID(nullptr) @@ -3680,8 +3675,6 @@ MediaStreamGraphImpl::MediaStreamGraphImpl(GraphDriverType aDriverRequested, , mGraphDriverAsleep(false) , mMonitor("MediaStreamGraphImpl") , mLifecycleState(LIFECYCLE_THREAD_NOT_STARTED) - // An offline graph is not initially processing. - , mEndTime(aDriverRequested == OFFLINE_THREAD_DRIVER ? 0 : GRAPH_TIME_MAX) , mForceShutDown(false) , mPostedRunInStableStateEvent(false) , mDetectedNotRunning(false) @@ -3855,11 +3848,6 @@ MediaStreamGraph::DestroyNonRealtimeInstance(MediaStreamGraph* aGraph) MediaStreamGraphImpl* graph = static_cast(aGraph); - if (!graph->mNonRealtimeProcessing) { - // Start the graph, but don't produce anything - graph->StartNonRealtimeProcessing(0); - } - graph->ForceShutDown(nullptr); } @@ -3906,13 +3894,6 @@ MediaStreamGraphImpl::CollectReports(nsIHandleReportCallback* aHandleReport, nsCOMPtr mHandlerData; }; - // When a non-realtime graph has not started, there is no thread yet, so - // collect sizes on this thread. - if (!(mRealtime || mNonRealtimeProcessing)) { - CollectSizesForMemoryReport(do_AddRef(aHandleReport), do_AddRef(aData)); - return NS_OK; - } - AppendMessage(MakeUnique(this, aHandleReport, aData)); return NS_OK; @@ -4352,11 +4333,26 @@ MediaStreamGraph::StartNonRealtimeProcessing(uint32_t aTicksToProcess) if (graph->mNonRealtimeProcessing) return; - graph->mEndTime = - graph->RoundUpToEndOfAudioBlock(graph->mStateComputedTime + - aTicksToProcess); + class Message : public ControlMessage { + public: + explicit Message(MediaStreamGraphImpl* aGraph, uint32_t aTicksToProcess) + : ControlMessage(nullptr) + , mGraph(aGraph) + , mTicksToProcess(aTicksToProcess) + {} + void Run() override + { + mGraph->mEndTime = + mGraph->RoundUpToEndOfAudioBlock(mGraph->mStateComputedTime + + mTicksToProcess); + } + // The graph owns this message. + MediaStreamGraphImpl* MOZ_NON_OWNING_REF mGraph; + uint32_t mTicksToProcess; + }; + graph->mNonRealtimeProcessing = true; - graph->EnsureRunInStableState(); + graph->AppendMessage(MakeUnique(graph, aTicksToProcess)); } void diff --git a/dom/media/MediaStreamGraphImpl.h b/dom/media/MediaStreamGraphImpl.h index 868ca370fd07..800e5f31fc3a 100644 --- a/dom/media/MediaStreamGraphImpl.h +++ b/dom/media/MediaStreamGraphImpl.h @@ -671,6 +671,10 @@ public: * at this time. This is behind mStateComputedTime during processing. */ GraphTime mProcessedTime = 0; + /** + * The graph should stop processing at this time. + */ + GraphTime mEndTime; /** * Date of the last time we updated the main thread with the graph state. */ @@ -812,11 +816,6 @@ public: #endif return mLifecycleState; } - /** - * The graph should stop processing at or after this time. - * Only set on main thread. Read on both main and MSG thread. - */ - Atomic mEndTime; /** * True when we need to do a forced shutdown during application shutdown.