зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1586370 - Pass IterationEnd up to the graph rather than back-querying the driver. r=padenot
This makes it simpler to maintain state in the GraphDriver in more complex cases, such as when an AudioCallbackDriver is backed by a fallback driver. Differential Revision: https://phabricator.services.mozilla.com/D57553 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
712efff333
Коммит
a4fbb9b878
|
@ -167,7 +167,7 @@ bool SystemClockDriver::IsFallback() { return mIsFallback; }
|
|||
void ThreadedDriver::RunThread() {
|
||||
mThreadRunning = true;
|
||||
while (true) {
|
||||
mIterationStart = IterationEnd();
|
||||
mIterationStart = mIterationEnd;
|
||||
mIterationEnd += GetIntervalForIteration();
|
||||
|
||||
if (mStateComputedTime < mIterationEnd) {
|
||||
|
@ -202,7 +202,8 @@ void ThreadedDriver::RunThread() {
|
|||
(long)nextStateComputedTime));
|
||||
|
||||
mStateComputedTime = nextStateComputedTime;
|
||||
IterationResult result = Graph()->OneIteration(mStateComputedTime, nullptr);
|
||||
IterationResult result =
|
||||
Graph()->OneIteration(mStateComputedTime, mIterationEnd, nullptr);
|
||||
|
||||
if (result.IsStop()) {
|
||||
// Signal that we're done stopping.
|
||||
|
@ -231,7 +232,7 @@ MediaTime SystemClockDriver::GetIntervalForIteration() {
|
|||
|
||||
MOZ_LOG(gMediaTrackGraphLog, LogLevel::Verbose,
|
||||
("%p: Updating current time to %f (real %f, StateComputedTime() %f)",
|
||||
Graph(), MediaTimeToSeconds(IterationEnd() + interval),
|
||||
Graph(), MediaTimeToSeconds(mIterationEnd + interval),
|
||||
(now - mInitialTimeStamp).ToSeconds(),
|
||||
MediaTimeToSeconds(mStateComputedTime)));
|
||||
|
||||
|
@ -726,8 +727,9 @@ long AudioCallbackDriver::DataCallback(const AudioDataValue* aInputBuffer,
|
|||
|
||||
bool iterate = mBuffer.Available();
|
||||
IterationResult result =
|
||||
iterate ? Graph()->OneIteration(nextStateComputedTime, &mMixer)
|
||||
: IterationResult::CreateStillProcessing();
|
||||
iterate
|
||||
? Graph()->OneIteration(nextStateComputedTime, mIterationEnd, &mMixer)
|
||||
: IterationResult::CreateStillProcessing();
|
||||
if (iterate) {
|
||||
// We totally filled the buffer (and mScratchBuffer isn't empty).
|
||||
// We don't need to run an iteration and if we do so we may overflow.
|
||||
|
|
|
@ -178,7 +178,8 @@ struct GraphInterface {
|
|||
virtual void DeviceChanged() = 0;
|
||||
/* Called by GraphDriver to iterate the graph. Output from the graph gets
|
||||
* mixed into aMixer, if it is non-null. */
|
||||
virtual IterationResult OneIteration(GraphTime aStateEnd,
|
||||
virtual IterationResult OneIteration(GraphTime aStateComputedEnd,
|
||||
GraphTime aIterationEnd,
|
||||
AudioMixer* aMixer) = 0;
|
||||
#ifdef DEBUG
|
||||
/* True if we're on aDriver's thread, or if we're on mGraphRunner's thread
|
||||
|
@ -271,8 +272,6 @@ class GraphDriver {
|
|||
GraphDriver* PreviousDriver();
|
||||
void SetPreviousDriver(GraphDriver* aPreviousDriver);
|
||||
|
||||
GraphTime IterationEnd() { return mIterationEnd; }
|
||||
|
||||
virtual AudioCallbackDriver* AsAudioCallbackDriver() { return nullptr; }
|
||||
|
||||
virtual OfflineClockDriver* AsOfflineClockDriver() { return nullptr; }
|
||||
|
@ -314,11 +313,9 @@ class GraphDriver {
|
|||
}
|
||||
|
||||
protected:
|
||||
// Time of the start of this graph iteration. This must be accessed while
|
||||
// having the monitor.
|
||||
// Time of the start of this graph iteration.
|
||||
GraphTime mIterationStart = 0;
|
||||
// Time of the end of this graph iteration. This must be accessed while having
|
||||
// the monitor.
|
||||
// Time of the end of this graph iteration.
|
||||
GraphTime mIterationEnd = 0;
|
||||
// Time until which the graph has processed data.
|
||||
GraphTime mStateComputedTime = 0;
|
||||
|
|
|
@ -56,13 +56,13 @@ void GraphRunner::Shutdown() {
|
|||
mThread->Shutdown();
|
||||
}
|
||||
|
||||
auto GraphRunner::OneIteration(GraphTime aStateEnd, AudioMixer* aMixer)
|
||||
-> IterationResult {
|
||||
auto GraphRunner::OneIteration(GraphTime aStateEnd, GraphTime aIterationEnd,
|
||||
AudioMixer* aMixer) -> IterationResult {
|
||||
TRACE_AUDIO_CALLBACK();
|
||||
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
MOZ_ASSERT(mThreadState == ThreadState::Wait);
|
||||
mIterationState = Some(IterationState(aStateEnd, aMixer));
|
||||
mIterationState = Some(IterationState(aStateEnd, aIterationEnd, aMixer));
|
||||
|
||||
#ifdef DEBUG
|
||||
if (auto audioDriver = mGraph->CurrentDriver()->AsAudioCallbackDriver()) {
|
||||
|
@ -109,6 +109,7 @@ NS_IMETHODIMP GraphRunner::Run() {
|
|||
MOZ_DIAGNOSTIC_ASSERT(mIterationState.isSome());
|
||||
TRACE();
|
||||
mIterationResult = mGraph->OneIterationImpl(mIterationState->StateEnd(),
|
||||
mIterationState->IterationEnd(),
|
||||
mIterationState->Mixer());
|
||||
// Signal that mIterationResult was updated
|
||||
mThreadState = ThreadState::Wait;
|
||||
|
|
|
@ -32,10 +32,11 @@ class GraphRunner final : public Runnable {
|
|||
MOZ_CAN_RUN_SCRIPT void Shutdown();
|
||||
|
||||
/**
|
||||
* Signals one iteration of mGraph. Hands aStateEnd over to mThread and runs
|
||||
* Signals one iteration of mGraph. Hands state over to mThread and runs
|
||||
* the iteration there.
|
||||
*/
|
||||
IterationResult OneIteration(GraphTime aStateEnd, AudioMixer* aMixer);
|
||||
IterationResult OneIteration(GraphTime aStateEnd, GraphTime aIterationEnd,
|
||||
AudioMixer* aMixer);
|
||||
|
||||
/**
|
||||
* Runs mGraph until it shuts down.
|
||||
|
@ -62,17 +63,21 @@ class GraphRunner final : public Runnable {
|
|||
|
||||
class IterationState {
|
||||
GraphTime mStateEnd;
|
||||
GraphTime mIterationEnd;
|
||||
AudioMixer* MOZ_NON_OWNING_REF mMixer;
|
||||
|
||||
public:
|
||||
IterationState(GraphTime aStateEnd, AudioMixer* aMixer)
|
||||
: mStateEnd(aStateEnd), mMixer(aMixer) {}
|
||||
IterationState(GraphTime aStateEnd, GraphTime aIterationEnd,
|
||||
AudioMixer* aMixer)
|
||||
: mStateEnd(aStateEnd), mIterationEnd(aIterationEnd), mMixer(aMixer) {}
|
||||
IterationState& operator=(const IterationState& aOther) {
|
||||
mStateEnd = aOther.mStateEnd;
|
||||
mIterationEnd = aOther.mIterationEnd;
|
||||
mMixer = aOther.mMixer;
|
||||
return *this;
|
||||
}
|
||||
GraphTime StateEnd() const { return mStateEnd; }
|
||||
GraphTime IterationEnd() const { return mIterationEnd; }
|
||||
AudioMixer* Mixer() const { return mMixer; }
|
||||
};
|
||||
|
||||
|
|
|
@ -126,7 +126,7 @@ TrackTime MediaTrackGraphImpl::GraphTimeToTrackTimeWithBlocking(
|
|||
|
||||
GraphTime MediaTrackGraphImpl::IterationEnd() const {
|
||||
MOZ_ASSERT(OnGraphThread());
|
||||
return CurrentDriver()->IterationEnd();
|
||||
return mIterationEndTime;
|
||||
}
|
||||
|
||||
void MediaTrackGraphImpl::UpdateCurrentTimeForTracks(
|
||||
|
@ -1302,20 +1302,24 @@ bool MediaTrackGraphImpl::UpdateMainThreadState() {
|
|||
return true;
|
||||
}
|
||||
|
||||
auto MediaTrackGraphImpl::OneIteration(GraphTime aStateEnd, AudioMixer* aMixer)
|
||||
-> IterationResult {
|
||||
auto MediaTrackGraphImpl::OneIteration(GraphTime aStateEnd,
|
||||
GraphTime aIterationEnd,
|
||||
AudioMixer* aMixer) -> IterationResult {
|
||||
if (mGraphRunner) {
|
||||
return mGraphRunner->OneIteration(aStateEnd, aMixer);
|
||||
return mGraphRunner->OneIteration(aStateEnd, aIterationEnd, aMixer);
|
||||
}
|
||||
|
||||
return OneIterationImpl(aStateEnd, aMixer);
|
||||
return OneIterationImpl(aStateEnd, aIterationEnd, aMixer);
|
||||
}
|
||||
|
||||
auto MediaTrackGraphImpl::OneIterationImpl(GraphTime aStateEnd,
|
||||
GraphTime aIterationEnd,
|
||||
AudioMixer* aMixer)
|
||||
-> IterationResult {
|
||||
TRACE_AUDIO_CALLBACK();
|
||||
|
||||
mIterationEndTime = aIterationEnd;
|
||||
|
||||
if (SoftRealTimeLimitReached()) {
|
||||
DemoteThreadFromRealTime();
|
||||
}
|
||||
|
|
|
@ -216,13 +216,14 @@ class MediaTrackGraphImpl : public MediaTrackGraph,
|
|||
* OneIterationImpl is called directly. Output from the graph gets mixed into
|
||||
* aMixer, if it is non-null.
|
||||
*/
|
||||
IterationResult OneIteration(GraphTime aStateEnd,
|
||||
IterationResult OneIteration(GraphTime aStateEnd, GraphTime aIterationEnd,
|
||||
AudioMixer* aMixer) override;
|
||||
|
||||
/**
|
||||
* Returns true if this MediaTrackGraph should keep running
|
||||
*/
|
||||
IterationResult OneIterationImpl(GraphTime aStateEnd, AudioMixer* aMixer);
|
||||
IterationResult OneIterationImpl(GraphTime aStateEnd, GraphTime aIterationEnd,
|
||||
AudioMixer* aMixer);
|
||||
|
||||
/**
|
||||
* Called from the driver, when the graph thread is about to stop, to tell
|
||||
|
@ -725,6 +726,10 @@ class MediaTrackGraphImpl : public MediaTrackGraph,
|
|||
* at this time. This is behind mStateComputedTime during processing.
|
||||
*/
|
||||
GraphTime mProcessedTime = 0;
|
||||
/**
|
||||
* The end of the current iteration. Only access on the graph thread.
|
||||
*/
|
||||
GraphTime mIterationEndTime = 0;
|
||||
/**
|
||||
* The graph should stop processing at this time.
|
||||
*/
|
||||
|
|
|
@ -30,7 +30,7 @@ class MockGraphInterface : public GraphInterface {
|
|||
MOCK_METHOD0(DeviceChanged, void());
|
||||
/* OneIteration cannot be mocked because IterationResult is non-memmovable and
|
||||
* cannot be passed as a parameter, which GMock does internally. */
|
||||
IterationResult OneIteration(GraphTime, AudioMixer*) {
|
||||
IterationResult OneIteration(GraphTime, GraphTime, AudioMixer*) {
|
||||
return mKeepProcessing ? IterationResult::CreateStillProcessing()
|
||||
: IterationResult::CreateStop(
|
||||
NS_NewRunnableFunction(__func__, [] {}));
|
||||
|
|
Загрузка…
Ссылка в новой задаче