зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1415556 - P3. clearly mark functions' thread use. r=padenot
MozReview-Commit-ID: BXmdk4zBo28 --HG-- extra : rebase_source : 4afd6fa5e887aff093e7a9e629e8c93573f17631
This commit is contained in:
Родитель
9b9c8f3ee4
Коммит
2eda28dd35
|
@ -66,8 +66,8 @@ static nsDataHashtable<nsUint32HashKey, MediaStreamGraphImpl*> gGraphs;
|
|||
|
||||
MediaStreamGraphImpl::~MediaStreamGraphImpl()
|
||||
{
|
||||
NS_ASSERTION(IsEmpty(),
|
||||
"All streams should have been destroyed by messages from the main thread");
|
||||
MOZ_ASSERT(mStreams.IsEmpty() && mSuspendedStreams.IsEmpty(),
|
||||
"All streams should have been destroyed by messages from the main thread");
|
||||
LOG(LogLevel::Debug, ("MediaStreamGraph %p destroyed", this));
|
||||
LOG(LogLevel::Debug, ("MediaStreamGraphImpl::~MediaStreamGraphImpl"));
|
||||
}
|
||||
|
@ -75,6 +75,7 @@ MediaStreamGraphImpl::~MediaStreamGraphImpl()
|
|||
void
|
||||
MediaStreamGraphImpl::FinishStream(MediaStream* aStream)
|
||||
{
|
||||
MOZ_ASSERT(OnGraphThreadOrNotRunning());
|
||||
if (aStream->mFinished)
|
||||
return;
|
||||
LOG(LogLevel::Debug, ("MediaStream %p will finish", aStream));
|
||||
|
@ -99,6 +100,7 @@ MediaStreamGraphImpl::FinishStream(MediaStream* aStream)
|
|||
void
|
||||
MediaStreamGraphImpl::AddStreamGraphThread(MediaStream* aStream)
|
||||
{
|
||||
MOZ_ASSERT(OnGraphThreadOrNotRunning());
|
||||
aStream->mTracksStartTime = mProcessedTime;
|
||||
|
||||
if (aStream->AsSourceStream()) {
|
||||
|
@ -134,6 +136,7 @@ MediaStreamGraphImpl::AddStreamGraphThread(MediaStream* aStream)
|
|||
void
|
||||
MediaStreamGraphImpl::RemoveStreamGraphThread(MediaStream* aStream)
|
||||
{
|
||||
MOZ_ASSERT(OnGraphThreadOrNotRunning());
|
||||
// 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.
|
||||
|
@ -174,6 +177,7 @@ MediaStreamGraphImpl::ExtractPendingInput(SourceMediaStream* aStream,
|
|||
GraphTime aDesiredUpToTime,
|
||||
bool* aEnsureNextIteration)
|
||||
{
|
||||
MOZ_ASSERT(OnGraphThread());
|
||||
bool finished;
|
||||
{
|
||||
MutexAutoLock lock(aStream->mMutex);
|
||||
|
@ -331,12 +335,14 @@ MediaStreamGraphImpl::GraphTimeToStreamTimeWithBlocking(MediaStream* aStream,
|
|||
GraphTime
|
||||
MediaStreamGraphImpl::IterationEnd() const
|
||||
{
|
||||
MOZ_ASSERT(OnGraphThreadOrNotRunning());
|
||||
return CurrentDriver()->IterationEnd();
|
||||
}
|
||||
|
||||
void
|
||||
MediaStreamGraphImpl::UpdateCurrentTimeForStreams(GraphTime aPrevCurrentTime)
|
||||
{
|
||||
MOZ_ASSERT(OnGraphThread());
|
||||
for (MediaStream* stream : AllStreams()) {
|
||||
bool isAnyBlocked = stream->mStartBlocking < mStateComputedTime;
|
||||
bool isAnyUnblocked = stream->mStartBlocking > aPrevCurrentTime;
|
||||
|
@ -400,6 +406,7 @@ MediaStreamGraphImpl::ProcessChunkMetadataForInterval(MediaStream* aStream,
|
|||
StreamTime aStart,
|
||||
StreamTime aEnd)
|
||||
{
|
||||
MOZ_ASSERT(OnGraphThreadOrNotRunning());
|
||||
MOZ_ASSERT(aStream);
|
||||
MOZ_ASSERT(IsTrackIDExplicit(aTrackID));
|
||||
|
||||
|
@ -436,6 +443,7 @@ MediaStreamGraphImpl::ProcessChunkMetadataForInterval(MediaStream* aStream,
|
|||
void
|
||||
MediaStreamGraphImpl::ProcessChunkMetadata(GraphTime aPrevCurrentTime)
|
||||
{
|
||||
MOZ_ASSERT(OnGraphThreadOrNotRunning());
|
||||
for (MediaStream* stream : AllStreams()) {
|
||||
StreamTime iterationStart = stream->GraphTimeToStreamTime(aPrevCurrentTime);
|
||||
StreamTime iterationEnd = stream->GraphTimeToStreamTime(mProcessedTime);
|
||||
|
@ -503,7 +511,7 @@ namespace {
|
|||
bool
|
||||
MediaStreamGraphImpl::AudioTrackPresent(bool& aNeedsAEC)
|
||||
{
|
||||
AssertOnGraphThreadOrNotRunning();
|
||||
MOZ_ASSERT(OnGraphThreadOrNotRunning());
|
||||
|
||||
bool audioTrackPresent = false;
|
||||
for (uint32_t i = 0; i < mStreams.Length() && audioTrackPresent == false; ++i) {
|
||||
|
@ -545,6 +553,7 @@ MediaStreamGraphImpl::AudioTrackPresent(bool& aNeedsAEC)
|
|||
void
|
||||
MediaStreamGraphImpl::UpdateStreamOrder()
|
||||
{
|
||||
MOZ_ASSERT(OnGraphThreadOrNotRunning());
|
||||
bool shouldAEC = false;
|
||||
bool audioTrackPresent = AudioTrackPresent(shouldAEC);
|
||||
|
||||
|
@ -780,6 +789,7 @@ MediaStreamGraphImpl::NotifyHasCurrentData(MediaStream* aStream)
|
|||
void
|
||||
MediaStreamGraphImpl::CreateOrDestroyAudioStreams(MediaStream* aStream)
|
||||
{
|
||||
MOZ_ASSERT(OnGraphThreadOrNotRunning());
|
||||
MOZ_ASSERT(mRealtime, "Should only attempt to create audio streams in real-time mode");
|
||||
|
||||
if (aStream->mAudioOutputs.IsEmpty()) {
|
||||
|
@ -846,6 +856,7 @@ MediaStreamGraphImpl::CreateOrDestroyAudioStreams(MediaStream* aStream)
|
|||
StreamTime
|
||||
MediaStreamGraphImpl::PlayAudio(MediaStream* aStream)
|
||||
{
|
||||
MOZ_ASSERT(OnGraphThreadOrNotRunning());
|
||||
MOZ_ASSERT(mRealtime, "Should only attempt to play audio in realtime mode");
|
||||
|
||||
float volume = 0.0f;
|
||||
|
@ -961,6 +972,7 @@ void
|
|||
MediaStreamGraphImpl::OpenAudioInputImpl(int aID,
|
||||
AudioDataListener *aListener)
|
||||
{
|
||||
MOZ_ASSERT(OnGraphThreadOrNotRunning());
|
||||
// Bug 1238038 Need support for multiple mics at once
|
||||
if (mInputDeviceUsers.Count() > 0 &&
|
||||
!mInputDeviceUsers.Get(aListener, nullptr)) {
|
||||
|
@ -1042,6 +1054,7 @@ MediaStreamGraphImpl::OpenAudioInput(int aID,
|
|||
void
|
||||
MediaStreamGraphImpl::CloseAudioInputImpl(AudioDataListener *aListener)
|
||||
{
|
||||
MOZ_ASSERT(OnGraphThreadOrNotRunning());
|
||||
uint32_t count;
|
||||
DebugOnly<bool> result = mInputDeviceUsers.Get(aListener, &count);
|
||||
MOZ_ASSERT(result);
|
||||
|
@ -1125,14 +1138,24 @@ MediaStreamGraph::OnGraphThreadOrNotRunning() const
|
|||
// via CurrentDriver().
|
||||
MediaStreamGraphImpl const * graph =
|
||||
static_cast<MediaStreamGraphImpl const *>(this);
|
||||
// if all the safety checks fail, assert we own the monitor
|
||||
return graph->mDetectedNotRunning ?
|
||||
NS_IsMainThread() : graph->mDriver->OnThread();
|
||||
}
|
||||
|
||||
bool
|
||||
MediaStreamGraph::OnGraphThread() const
|
||||
{
|
||||
// we're on the right thread (and calling mDriver is safe),
|
||||
MediaStreamGraphImpl const * graph =
|
||||
static_cast<MediaStreamGraphImpl const *>(this);
|
||||
MOZ_ASSERT(graph->mDriver);
|
||||
return graph->mDriver->OnThread();
|
||||
}
|
||||
|
||||
bool
|
||||
MediaStreamGraphImpl::ShouldUpdateMainThread()
|
||||
{
|
||||
MOZ_ASSERT(OnGraphThreadOrNotRunning());
|
||||
if (mRealtime) {
|
||||
return true;
|
||||
}
|
||||
|
@ -1148,6 +1171,7 @@ MediaStreamGraphImpl::ShouldUpdateMainThread()
|
|||
void
|
||||
MediaStreamGraphImpl::PrepareUpdatesToMainThreadState(bool aFinalUpdate)
|
||||
{
|
||||
MOZ_ASSERT(OnGraphThreadOrNotRunning());
|
||||
mMonitor.AssertCurrentThreadOwns();
|
||||
|
||||
// We don't want to frequently update the main thread about timing update
|
||||
|
@ -1216,6 +1240,7 @@ void
|
|||
MediaStreamGraphImpl::ProduceDataForStreamsBlockByBlock(uint32_t aStreamIndex,
|
||||
TrackRate aSampleRate)
|
||||
{
|
||||
MOZ_ASSERT(OnGraphThread());
|
||||
MOZ_ASSERT(aStreamIndex <= mFirstCycleBreaker,
|
||||
"Cycle breaker is not AudioNodeStream?");
|
||||
GraphTime t = mProcessedTime;
|
||||
|
@ -1242,6 +1267,7 @@ MediaStreamGraphImpl::ProduceDataForStreamsBlockByBlock(uint32_t aStreamIndex,
|
|||
bool
|
||||
MediaStreamGraphImpl::AllFinishedStreamsNotified()
|
||||
{
|
||||
MOZ_ASSERT(OnGraphThread());
|
||||
for (MediaStream* stream : AllStreams()) {
|
||||
if (stream->mFinished && !stream->mNotifiedFinished) {
|
||||
return false;
|
||||
|
@ -1253,7 +1279,7 @@ MediaStreamGraphImpl::AllFinishedStreamsNotified()
|
|||
void
|
||||
MediaStreamGraphImpl::RunMessageAfterProcessing(UniquePtr<ControlMessage> aMessage)
|
||||
{
|
||||
MOZ_ASSERT(CurrentDriver()->OnThread());
|
||||
MOZ_ASSERT(OnGraphThread());
|
||||
|
||||
if (mFrontMessageQueue.IsEmpty()) {
|
||||
mFrontMessageQueue.AppendElement();
|
||||
|
@ -1267,6 +1293,7 @@ MediaStreamGraphImpl::RunMessageAfterProcessing(UniquePtr<ControlMessage> aMessa
|
|||
void
|
||||
MediaStreamGraphImpl::RunMessagesInQueue()
|
||||
{
|
||||
MOZ_ASSERT(OnGraphThread());
|
||||
// Calculate independent action times for each batch of messages (each
|
||||
// batch corresponding to an event loop task). This isolates the performance
|
||||
// of different scripts to some extent.
|
||||
|
@ -1283,6 +1310,7 @@ MediaStreamGraphImpl::RunMessagesInQueue()
|
|||
void
|
||||
MediaStreamGraphImpl::UpdateGraph(GraphTime aEndBlockingDecisions)
|
||||
{
|
||||
MOZ_ASSERT(OnGraphThread());
|
||||
MOZ_ASSERT(aEndBlockingDecisions >= mProcessedTime);
|
||||
// The next state computed time can be the same as the previous: it
|
||||
// means the driver would be have been blocking indefinitly, but the graph has
|
||||
|
@ -1343,6 +1371,7 @@ MediaStreamGraphImpl::UpdateGraph(GraphTime aEndBlockingDecisions)
|
|||
void
|
||||
MediaStreamGraphImpl::Process()
|
||||
{
|
||||
MOZ_ASSERT(OnGraphThread());
|
||||
// Play stream contents.
|
||||
bool allBlockedForever = true;
|
||||
// True when we've done ProcessInput for all processed streams.
|
||||
|
@ -1424,6 +1453,7 @@ MediaStreamGraphImpl::Process()
|
|||
bool
|
||||
MediaStreamGraphImpl::UpdateMainThreadState()
|
||||
{
|
||||
MOZ_ASSERT(OnGraphThread());
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
bool finalUpdate = mForceShutDown ||
|
||||
(mProcessedTime >= mEndTime && AllFinishedStreamsNotified()) ||
|
||||
|
@ -1450,6 +1480,7 @@ MediaStreamGraphImpl::UpdateMainThreadState()
|
|||
bool
|
||||
MediaStreamGraphImpl::OneIteration(GraphTime aStateEnd)
|
||||
{
|
||||
MOZ_ASSERT(OnGraphThread());
|
||||
WebCore::DenormalDisabler disabler;
|
||||
|
||||
// Process graph message from the main thread for this iteration.
|
||||
|
@ -1479,6 +1510,7 @@ MediaStreamGraphImpl::OneIteration(GraphTime aStateEnd)
|
|||
void
|
||||
MediaStreamGraphImpl::ApplyStreamUpdate(StreamUpdate* aUpdate)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mMonitor.AssertCurrentThreadOwns();
|
||||
|
||||
MediaStream* stream = aUpdate->mStream;
|
||||
|
@ -1495,7 +1527,7 @@ MediaStreamGraphImpl::ApplyStreamUpdate(StreamUpdate* aUpdate)
|
|||
void
|
||||
MediaStreamGraphImpl::ForceShutDown(media::ShutdownTicket* aShutdownTicket)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Must be called on main thread");
|
||||
MOZ_ASSERT(NS_IsMainThread(), "Must be called on main thread");
|
||||
LOG(LogLevel::Debug, ("MediaStreamGraph %p ForceShutdown", this));
|
||||
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
|
@ -1525,6 +1557,7 @@ MediaStreamGraphImpl::ForceShutDown(media::ShutdownTicket* aShutdownTicket)
|
|||
NS_IMETHODIMP
|
||||
MediaStreamGraphImpl::Notify(nsITimer* aTimer)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
NS_ASSERTION(!mForceShutdownTicket, "MediaStreamGraph took too long to shut down!");
|
||||
// Sigh, graph took too long to shut down. Stop blocking system
|
||||
|
@ -1552,7 +1585,8 @@ public:
|
|||
{}
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
NS_ASSERTION(mGraph->mDetectedNotRunning,
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mGraph->mDetectedNotRunning && mGraph->mDriver,
|
||||
"We should know the graph thread control loop isn't running!");
|
||||
|
||||
LOG(LogLevel::Debug, ("Shutting down graph %p", mGraph.get()));
|
||||
|
@ -1592,6 +1626,7 @@ public:
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// mGraph's thread is not running so it's OK to do whatever here
|
||||
for (MediaStream* stream : mGraph->AllStreams()) {
|
||||
// Clean up all MediaSegments since we cannot release Images too
|
||||
// late during shutdown. Also notify listeners that they were removed
|
||||
|
@ -1610,7 +1645,6 @@ public:
|
|||
// stage, since completion of that stage requires all streams to be freed,
|
||||
// which requires shutdown to proceed.
|
||||
|
||||
// mGraph's thread is not running so it's OK to do whatever here
|
||||
if (mGraph->IsEmpty()) {
|
||||
// mGraph is no longer needed, so delete it.
|
||||
mGraph->Destroy();
|
||||
|
@ -1675,7 +1709,7 @@ public:
|
|||
void
|
||||
MediaStreamGraphImpl::RunInStableState(bool aSourceIsMSG)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Must be called on main thread");
|
||||
MOZ_ASSERT(NS_IsMainThread(), "Must be called on main thread");
|
||||
|
||||
nsTArray<nsCOMPtr<nsIRunnable> > runnables;
|
||||
// When we're doing a forced shutdown, pending control messages may be
|
||||
|
@ -1840,7 +1874,7 @@ MediaStreamGraphImpl::RunInStableState(bool aSourceIsMSG)
|
|||
void
|
||||
MediaStreamGraphImpl::EnsureRunInStableState()
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "main thread only");
|
||||
MOZ_ASSERT(NS_IsMainThread(), "main thread only");
|
||||
|
||||
if (mPostedRunInStableState)
|
||||
return;
|
||||
|
@ -1852,6 +1886,7 @@ MediaStreamGraphImpl::EnsureRunInStableState()
|
|||
void
|
||||
MediaStreamGraphImpl::EnsureStableStateEventPosted()
|
||||
{
|
||||
MOZ_ASSERT(OnGraphThread());
|
||||
mMonitor.AssertCurrentThreadOwns();
|
||||
|
||||
if (mPostedRunInStableStateEvent)
|
||||
|
@ -3526,7 +3561,7 @@ uint32_t WindowToHash(nsPIDOMWindowInner* aWindow)
|
|||
MediaStreamGraph*
|
||||
MediaStreamGraph::GetInstanceIfExists(nsPIDOMWindowInner* aWindow)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Main thread only");
|
||||
MOZ_ASSERT(NS_IsMainThread(), "Main thread only");
|
||||
|
||||
uint32_t hashkey = WindowToHash(aWindow);
|
||||
|
||||
|
@ -3539,7 +3574,7 @@ MediaStreamGraph*
|
|||
MediaStreamGraph::GetInstance(MediaStreamGraph::GraphDriverType aGraphDriverRequested,
|
||||
nsPIDOMWindowInner* aWindow)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Main thread only");
|
||||
MOZ_ASSERT(NS_IsMainThread(), "Main thread only");
|
||||
|
||||
MediaStreamGraphImpl* graph =
|
||||
static_cast<MediaStreamGraphImpl*>(GetInstanceIfExists(aWindow));
|
||||
|
@ -3606,7 +3641,7 @@ MediaStreamGraph*
|
|||
MediaStreamGraph::CreateNonRealtimeInstance(TrackRate aSampleRate,
|
||||
nsPIDOMWindowInner* aWindow)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Main thread only");
|
||||
MOZ_ASSERT(NS_IsMainThread(), "Main thread only");
|
||||
|
||||
nsCOMPtr<nsIGlobalObject> parentObject = do_QueryInterface(aWindow);
|
||||
MediaStreamGraphImpl* graph = new MediaStreamGraphImpl(
|
||||
|
@ -3622,7 +3657,7 @@ MediaStreamGraph::CreateNonRealtimeInstance(TrackRate aSampleRate,
|
|||
void
|
||||
MediaStreamGraph::DestroyNonRealtimeInstance(MediaStreamGraph* aGraph)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Main thread only");
|
||||
MOZ_ASSERT(NS_IsMainThread(), "Main thread only");
|
||||
MOZ_ASSERT(aGraph->IsNonRealtime(), "Should not destroy the global graph here");
|
||||
|
||||
MediaStreamGraphImpl* graph = static_cast<MediaStreamGraphImpl*>(aGraph);
|
||||
|
@ -3641,6 +3676,7 @@ NS_IMETHODIMP
|
|||
MediaStreamGraphImpl::CollectReports(nsIHandleReportCallback* aHandleReport,
|
||||
nsISupports* aData, bool aAnonymize)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
if (mLifecycleState >= LIFECYCLE_WAITING_FOR_THREAD_SHUTDOWN) {
|
||||
// Shutting down, nothing to report.
|
||||
FinishCollectReports(aHandleReport, aData, nsTArray<AudioNodeSizes>());
|
||||
|
@ -3878,6 +3914,7 @@ MediaStreamGraph::NotifyWhenGraphStarted(AudioNodeStream* aStream)
|
|||
void
|
||||
MediaStreamGraphImpl::IncrementSuspendCount(MediaStream* aStream)
|
||||
{
|
||||
MOZ_ASSERT(OnGraphThreadOrNotRunning());
|
||||
if (!aStream->IsSuspended()) {
|
||||
MOZ_ASSERT(mStreams.Contains(aStream));
|
||||
mStreams.RemoveElement(aStream);
|
||||
|
@ -3890,6 +3927,7 @@ MediaStreamGraphImpl::IncrementSuspendCount(MediaStream* aStream)
|
|||
void
|
||||
MediaStreamGraphImpl::DecrementSuspendCount(MediaStream* aStream)
|
||||
{
|
||||
MOZ_ASSERT(OnGraphThreadOrNotRunning());
|
||||
bool wasSuspended = aStream->IsSuspended();
|
||||
aStream->DecrementSuspendCount();
|
||||
if (wasSuspended && !aStream->IsSuspended()) {
|
||||
|
@ -3908,6 +3946,7 @@ void
|
|||
MediaStreamGraphImpl::SuspendOrResumeStreams(AudioContextOperation aAudioContextOperation,
|
||||
const nsTArray<MediaStream*>& aStreamSet)
|
||||
{
|
||||
MOZ_ASSERT(OnGraphThreadOrNotRunning());
|
||||
// For our purpose, Suspend and Close are equivalent: we want to remove the
|
||||
// streams from the set of streams that are going to be processed.
|
||||
for (MediaStream* stream : aStreamSet) {
|
||||
|
@ -3968,7 +4007,7 @@ MediaStreamGraphImpl::ApplyAudioContextOperationImpl(
|
|||
MediaStream* aDestinationStream, const nsTArray<MediaStream*>& aStreams,
|
||||
AudioContextOperation aOperation, void* aPromise)
|
||||
{
|
||||
MOZ_ASSERT(CurrentDriver()->OnThread());
|
||||
MOZ_ASSERT(OnGraphThread());
|
||||
|
||||
SuspendOrResumeStreams(aOperation, aStreams);
|
||||
|
||||
|
@ -4111,7 +4150,7 @@ MediaStreamGraph::IsNonRealtime() const
|
|||
void
|
||||
MediaStreamGraph::StartNonRealtimeProcessing(uint32_t aTicksToProcess)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "main thread only");
|
||||
MOZ_ASSERT(NS_IsMainThread(), "main thread only");
|
||||
|
||||
MediaStreamGraphImpl* graph = static_cast<MediaStreamGraphImpl*>(this);
|
||||
NS_ASSERTION(!graph->mRealtime, "non-realtime only");
|
||||
|
|
|
@ -1393,6 +1393,7 @@ protected:
|
|||
// Intended only for assertions, either on graph thread or not running (in
|
||||
// which case we must be on the main thread).
|
||||
bool OnGraphThreadOrNotRunning() const;
|
||||
bool OnGraphThread() const;
|
||||
|
||||
// Media graph thread only
|
||||
nsTArray<nsCOMPtr<nsIRunnable> > mPendingUpdateRunnables;
|
||||
|
|
|
@ -417,6 +417,7 @@ public:
|
|||
*/
|
||||
void SetStreamOrderDirty()
|
||||
{
|
||||
MOZ_ASSERT(OnGraphThreadOrNotRunning());
|
||||
mStreamOrderDirty = true;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче